Reputation: 24984
Code:
unsigned int i = 1<<31;
printf("%d\n", i);
Why the out put is -2147483648
, a negative value?
Updated question:
#include <stdio.h>
int main(int argc, char * argv[]) {
int i = 1<<31;
unsigned int j = 1<<31;
printf("%u, %u\n", i, j);
printf("%d, %d\n", i, j);
return 0;
}
The above print:
2147483648, 2147483648
-2147483648, -2147483648
So, does this means, signed int & unsigned int have the same bit values, the difference is how you treat the 31st bit when convert it to a number value?
Upvotes: 2
Views: 1614
Reputation: 78973
You are not doing the shift operation on an unsigned
but on a signed int
.
1
is signed
.signed
(assuming that int
is 32 bit wide), that is already undefined behaviorunsigned
. unsigned
as a signed, again no defined behavior.Upvotes: 3
Reputation: 441
%u
is for unsigned int.
%d
is for signed int.
in your programs output :
2147483648, 2147483648 (output for unsigned int)
-2147483648, -2147483648 (output for signed int )
Upvotes: 2
Reputation: 4106
printf("%d\n", i);
invokes UB. i
is unsigned int
and you try to print it as signed int
. Writing 1 << 31
instead of 1U << 31
is undefined too.
Print it as:
printf("%u\n", i);
or
printf("%X\n", i);
About your updated question, it also invokes UB for the very same reasons (If you use '1U' instead of 1
, then for the reason that an int
is initialized with 1U << 31
which is out of range value. If an unsigned
is initialized with out of range value, modular arithmetic come into picture and remainder is assigned. For signed
the behavior is undefined.)
Understanding the behavior on your platform
On your platform, int appears to be 4 byte. When you write something like 1 << 31
, it converts to bit patters 0x80000000
on your machine.
Now when you try to print this pattern as signed, it prints signed interpretation which is -231 (AKA INT_MIN) in 2s completement system. When you print this as unsigned, you get expected 231 as output.
Learnings
1. Use 1U << 31
instead of 1 << 31
2. Always use correct print specifiers in printf.
3. Pass correct argument types to variadic functions.
4. Be careful when implicit typecast (unsigned -> signed, wider type -> narrow type) takes place. If possible, avoid such castings completely.
Upvotes: 4
Reputation: 2221
%d
prints the int
version of the unsigned int i
. Try %u
for unsigned int
.
printf("%u\n", i);
int main(){
printf("%d, %u",-1,-1);
return 0;
}
Output: -1, 4294967295
i.e The way a signed integer is stored and how it gets converted to signed from unsigned or vice-versa will help you. Follow this.
To answer your updated question, its how the system represents them i.e in a 2's complement (as in the above case where
-1 =2's complement of 1 = 4294967295
.
Upvotes: 5
Reputation: 300759
Use '%u
' for unsigned int
printf("%u\n", i);
.......................................................
Response to updated question: any sequence of bits can be interpreted as a signed or unsigned value.
Upvotes: 4
Reputation: 9411
Try
printf("%u\n", i);
By using %d
specifier, printf expects argument as int
and it typecast to int
.
So, use %u
for unsigned int
.
Upvotes: 3