我可以猜测后者明确指出将'1'视为无符号整数。但如果有任何前者,那么副作用会是什么呢?我看到这两个都在linux内核中使用。那么哪一个更准确/推荐?为什么?
答案 0 :(得分:3)
{1}}的一个问题变得明显,当你将1向左移动足够远时。在具有整数的二进制补码表示的机器上,这使得该值突然变为负值。假设1 << x
宽度为32位:
int
产量
#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;
}
在我的机器上。这在代码的其他部分可能是意外的。特别是,由于有符号扩展,反向移位不一定相同:
1073741824
-2147483648
1073741824d
2147483648d
产量
#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;
}
注意他在第二个输出线上翻了标牌......
答案 1 :(得分:1)
这取决于您运行此系统的系统 如果它是一个整数为16位的系统,那么(1 <&lt;&lt; 16)将“离开边缘”并且数字将为0.在32位系统上,该数字将是2 ^ 16(65536)。
由于班次为16,因此1是无符号也无关紧要 然而,如果转变为15,则更复杂:
在移位后,无符号16位整数的值为2 ^ 15(32768),而带符号的16位整数在二进制补码表示中的值为-2 ^ 15(-32768)