I can guess that the latter e开发者_运维知识库xplicitly indicates to treat the '1' as an unsigned integer. But what are the bad side-effects if any of the former. I see both of these being used in the linux kernel. So which one is the more accurate/recommended and why?
One problem with 1 << x
becomes obvious, when you shift the 1 far enough to the left. On machines with twos-complement representation for integers, this makes the value suddenly become negative. Assuming an int
width of 32 bits:
#include <stdio.h>
int
main(int argc, const char** argv)
{
printf("%d\n", (1 << 30));
printf("%d\n", (1 << 31));
printf("%ud\n", (1U << 30));
printf("%ud\n", (1U << 31));
return 0;
}
yields
1073741824
-2147483648
1073741824d
2147483648d
on my machine. This might be unexpected in other parts of the code. In particular, as the reverse shift is not necessarily equivalent, due to signed-extension:
#include <stdio.h>
int
main(int argc, const char** argv)
{
printf("%d\n", (2 << 29) >> 29);
printf("%d\n", (2 << 30) >> 30);
printf("%u\n", (2U << 29) >> 29);
printf("%u\n", (2U << 30) >> 30);
return 0;
}
yields
2
-2
2
2
Notice he flipped sign on the second output line...
This depends on the system you are running this on.
If it's a system where integers are 16-bit then (1 << 16) would "go off the edge" and the number would be 0. On a 32-bit system the number would be 2^16 (65536).
Since the shift is 16 then it really doesn't matter if 1 is unsigned or not.
However if the shift were to be 15 then it is more complicated:
An unsigned 16-bit integer would, after the shift, have the value of 2^15 (32768) while a signed 16-bit integer would have the value -2^15 (-32768) in a twos-complement representation.
精彩评论