Reputation: 339
I wrote this bit of code to learn about bit shifting. To my surprise, even though I declared x
to be an unsigned int
, the output includes a negative number, namely when the leftmost bit is set to 1. My question: why? I thought an unsigned int
was never negative. Per sizeof(x)
, x
is 4 bytes wide.
Here is the code fragment:
int main(void)
{
unsigned int x;
x = 1;
for (int i = 0; i < 32; i++)
{
printf("2^%i = %i\n", i, x);
x <<= 1;
}
return 0;
}
Here is the output:
2^0 = 1
2^1 = 2
2^2 = 4
2^3 = 8
2^4 = 16
2^5 = 32
2^6 = 64
2^7 = 128
2^8 = 256
2^9 = 512
2^10 = 1024
2^11 = 2048
2^12 = 4096
2^13 = 8192
2^14 = 16384
2^15 = 32768
2^16 = 65536
2^17 = 131072
2^18 = 262144
2^19 = 524288
2^20 = 1048576
2^21 = 2097152
2^22 = 4194304
2^23 = 8388608
2^24 = 16777216
2^25 = 33554432
2^26 = 67108864
2^27 = 134217728
2^28 = 268435456
2^29 = 536870912
2^30 = 1073741824
2^31 = -2147483648
Upvotes: 1
Views: 144
Reputation: 1313
According to the C++ reference page on printf, using %i in the string passed to printf means the corresponding argument will be treated as signed decimal integer. This means that your unsigned int will be casted to a signed int. In C++, casting unsigned to signed (and reverse) only changes the interpretation, not the bit values. So setting the leftmost bit to 1 makes the number negative because that is what it corresponds to in signed integer interpretation. To achieve the expected number, use %u instead for unsigned integer interpretation.
Upvotes: 1
Reputation: 133619
When you talk about the sign of a integral value in C (C++ and many other programming languages) you are just talking about how you interpret some data.
You must understand that what's stored inside an unsigned int
are just bits regardless of the sign, the fact that they behave as "unsigned" when used is a mere interpretation of the value.
So by using %i
specifier you are treating it as a signed value, regardless how it is declared. Try with %u
which specifies that you want to treat them as unsigned
.
Upvotes: 3
Reputation: 225197
You're using the %i
format specifier, which prints its argument as a signed int
.
If you want to print as unsigned, use the %u
format specifier.
printf("2^%i = %u\n", i, x);
Upvotes: 3
Reputation: 311088
Just use correct conversion symbol
printf("2^%u = %u\n", i, x);
Upvotes: 4