使用gcc(4.6.3)进行编译不会产生任何警告,因此会产生-2147483648。
printf ("%d", (1<<31));
编译它会产生“警告:表达式中的整数溢出[-Woverflow]”并生成2147483647作为结果。
printf ("%d". (1<<31)-1);
我很困惑为什么第二个表达式会给出整数溢出警告。
答案 0 :(得分:12)
虽然对于带符号的32位整数,1<<31
可能是未定义的行为,但它通常会产生最大负32位2的补码整数值(0x80000000 = -2147483648
)。如果您尝试从此值中减去1,则值下溢并成为最大正值,因此编译器警告。
1<<31 0x80000000 -2147483648
(1<<31)-1 0x80000000-1 = 0x7fffffff 2147483647
答案 1 :(得分:2)
%d
打印一个整数。执行(1<<31)
时,您将创建一个整数-2147483648
,这是最低的32位数。所以当你尝试(1<<31) - 1
时,你试图表示一个不能用32位表示的负数!所以它下溢并给你2147483647
(环绕)。
答案 2 :(得分:-1)
define MAXVAL ((long int) ((unsigned long) (1 << 31) - 1))
此构造摆脱了编译器警告。只需输入您需要的类型来处理数学和结果。这个使用unsigned long
来保存数学,然后将结果转换为所需的long int
类型。
现在正在编译:
long int x = MAXVAL;
这不会产生溢出警告。