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