b / n宏定义有什么不同:'#define my_macro(1<< 16)'和'#define my_macro(1U<< 16)'

时间:2011-07-14 10:39:58

标签: c macros

我可以猜测后者明确指出将'1'视为无符号整数。但如果有任何前者,那么副作用会是什么呢?我看到这两个都在linux内核中使用。那么哪一个更准确/推荐?为什么?

2 个答案:

答案 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)