3

用 gcc (4.6.3) 编译它不会产生任何警告并产生 -2147483648 作为结果。

printf ("%d", (1<<31));

编译它会产生“警告:表达式 [-Woverflow] 中的整数溢出”并产生 2147483647 作为结果。

printf ("%d". (1<<31)-1);

我很困惑为什么第二个表达式会给出整数溢出警告。

4

3 回答 3

13

尽管1<<31对于带符号的 32 位整数来说可以说是未定义的行为,但它通常会导致最大的负 32 位 2 的补码整数值 ( 0x80000000 = -2147483648)。如果您尝试从该值中减去 1,则该值下溢并成为最大正值,因此会发出编译器警告。

 1<<31      0x80000000                -2147483648
(1<<31)-1   0x80000000-1 = 0x7fffffff  2147483647 
于 2013-06-10T07:56:49.133 回答
2

%d打印一个整数。当你这样做时,(1<<31)你正在创建一个 integer -2147483648,它是最低的 32 位数字。因此,当您尝试(1<<31) - 1表示无法用 32 位表示的负数时!所以它下溢并给你2147483647 (环绕)。

于 2013-06-10T07:59:05.507 回答
-1
define MAXVAL ((long int) ((unsigned long) (1 << 31) - 1))

此构造消除了编译器警告。只需制作处理数学和结果所需的任何类型。这个使用一个unsigned long来保存数学,然后将结果转换为所需的类型long int

现在编译:

 long int x = MAXVAL;

这不会产生溢出警告

于 2014-08-29T15:11:17.430 回答