Re: possible overflow?



mr_semantics@xxxxxxxxxxx wrote:
> I am still fiddling with bitwise operations - this time I have been
> working on a program that accepts input (an unsigned integral) from
> the user, and then after some 'conversion' outputs that number in
> binary format. I have one problem that is vexing me though:
>
> #include <stdio.h>
>
> int main(void)
> {
> unsigned int input = 8;
> unsigned long int i;
> unsigned long int j = 0;
> size_t number_of_bits = sizeof(j) * 8;

In C, the number of bits in a byte is CHAR_BIT, a macro from
<limits.h>.
Also in C, not every bit needs to be a value/sign bit, some may be
purely padding. For instance, an implementation with 36-bit ints can
legally support 32-bit int values, having 4 unused padding bits.

>
>
> j = (1 << (number_of_bits - 1));

1 is an int, not an unsigned long. A single left shift performs a
multiplication by 2 on positive values. For _signed_ integers
though, if the mathematical number can not be represented
in the original integer type, the behaviour is not defined
by the C language. In other words, _anything_ can happen.

> for (i = 1; i != 0; i <<= 1) {
> if (input & j) {
> (void) putchar('1');
> } else {
> (void) putchar('0');
> }
> j >>= 1;
> }
> puts("");
> return 0;
> }

You don't need dual masks...

#include <stdio.h>

typedef unsigned int unsigned_integer_t;

int main(void)
{
unsigned_integer_t input = 8;
unsigned_integer_t mask;

mask = -1; /* all 1 bits : 1......1 [1] */
mask /= 2; /* leading 0 : 01.....1 */
mask++; /* high bit only : 10.....0 */

while (mask != 0)
{
putchar('0' + !!(input & mask));
mask >>= 1;
}

puts("");
return 0;
}

[1] The C standard explicitly defines the conversion of a signed
value to an unsigned integer type. This will produce the maximum
value for any unsigned integer type.

> That is a working program that gives an example of my problem - its
> output is:
>
> 0000000000000000000000000000111111111111111111111111111111111000

That's a classic example of what 'undefined behaviour' can yield.

--
Peter

.



Relevant Pages

  • Re: conversions
    ... than or equal to the rank of int and unsigned int. ... supported by an implementation that have lower conversion rank than int. ... "The rank of any unsigned integer type shall equal the rank of the corresponding signed integer type, ...
    (comp.lang.c)
  • Re: Ada Pointer Size Problem
    ... >> int. ... > pointer to an int. ... And you can't assign C pointer to integer without conversion; ... need not provide them if it doesn't have a suitable integer type. ...
    (comp.lang.ada)
  • Re: Bit-fields and integral promotion
    ... >> The standard very clearly intends to specify the behaviour. ... > whether declared as int or unsigned int, ... "A bit-field is interpreted as a signed or unsigned integer type ... any signed integer type with less precision." ...
    (comp.lang.c)
  • Re: Moving from C++ to VC++
    ... If it is the longest integer. ... have been bad to constrain fseek to 16 bit int offsets, so they used long, ... 8192 bit integer type is a very special type that is mind-boggling overkill ... Storing pointers in an integer is common enough that the C++ Standard ...
    (microsoft.public.vc.language)
  • Re: type conversion float and long
    ... > How does the type conversion work if the expression involves a float ... If an expression involves a float and any integer type, any at all, ... int" is not a qualifier, it is part of the type. ...
    (comp.lang.c)