[prog] c types confusion

dominik.schramm at gmxpro.net dominik.schramm at gmxpro.net
Wed Mar 24 15:24:08 EST 2004


Hi,

Alice Moomlyn <alice_moomlyn at yahoo.com> writes:

> #include <stdio.h>
>
> /* This program does not do what I expect it to do.

I can't see what it does on your computer, but on mine
it does what I expected -- with the exception of printf
(see below).

>    Firstly, I would have expected signed int
>    to wrap at 2^15, rather than 2^31.

Huh, why? Is that a typo/braino, or did you really mean
2^15?
The size of signed int is 4 bytes, or 32 bits, 
and 2^32 / 2 == 2^31.


0111 1111.1111 1111.1111 1111.1111 1111

is the largest possible positive integer that "signed int"
can store if sizeof(int) == 4, 
i.e. 2^31 - 1 == 2.147.483.647, not 2^31 !

Adding one makes the sign bit (bit 31) 1, thus the number
becomes negative:
                  0111 1111.1111 1111.1111 1111.1111 1111 + 1
== (1's compl. of 1000 0000.0000 0000.0000 0000.0000 0000) + 1
==  2's compl. of 1000 0000.0000 0000.0000 0000.0000 0000
==              "-1000 0000.0000 0000.0000 0000.0000 0000"
== -2.147.483.648 == -2^31

This is the most common example of the "wrapping" you were 
talking about.

As for multiplication:

0100 0000.0000 0000.0000 0000.0000 0000

  multiplied by 2 yields

1000 0000.0000 0000.0000 0000.0000 0000

and this again is -2.147.483.648 == -2^31

Uhm, are you familiar with 1's and 2's complements for finding
out the negative to a given number? 
The above calculations are all a bit confusing -- they even
tried to confuse me! -- because the sum 01111... + 1 happens to be
the same as the 1's complement of 01111...

>    Secondly, I would have expected unsigned int
>    to hold 2^31 quite confortable.
>    But instead it wrapped to a negative number.
>    Strange.

Well, it does. But this really took me some time until I 
figured it out myself:
You have to tell printf that the integer you want to output
is unsigned, of course! :-)

printf("%u", MyUnsignedInt);

Again, see printf(3).

>    Thirdly I would have expected float to start
>    losing precision well before 2^31.
>    But this didn't happen!

I don't understand the question. Can you elaborate on why you
think so?

> int main()
> {
>    int MyInt = 1;
>    unsigned int MyUnsignedInt = 1;
> [...]
>        printf("unsigned int: %d ", MyUnsignedInt);

printf("unsigned int: %u ", MyUnsignedInt);

hope this helps
regards,
dominik




More information about the Programming mailing list