首页 文章

理解2 ^ 31和-2 ^ 31整数提升

提问于
浏览
5
#include <stdio.h>

int main() {
    printf("sizeof(int): %zu\n", sizeof(int));
    printf("%d\n", 2147483648u > -2147483648);
    printf("%d\n", ((unsigned int)2147483648u) > ((int)-2147483648));
    printf("%d\n", 2147483648u != -2147483648);
    printf("%d\n", ((unsigned int)2147483648u) != ((int)-2147483648));
    return 0;
}

C和C中的此代码的输出,在cygwin64和具有gcc 5.2.0的rhel6.4机器上是:

sizeof(int): 4
1
0
1
0

根据“Integer promotions”, 2147483648u 的类型为 unsigned int (即使没有 u 后缀), -2147483648 类型为 int (与往常一样) . 为什么显式铸造会产生不同的结果?

根据“Usual arithmetic conversions”,本段适用:

否则,签名是不同的:如果具有无符号类型的操作数的转换等级大于或等于带符号操作数的类型的等级,则带有签名类型的操作数将隐式转换为无符号类型

这意味着正确的结果就像:

2147483648u > 2147483648u
2147483648u != 2147483648u

执行,因为在32位中,带符号-2 ^ 31和无符号2 ^ 31具有相同的表示 . 换句话说,铸造的结果是正确的 . 到底是怎么回事?

我觉得不知怎的,在没有强制转换的情况下应用更高级别的整数提升,所以我得到了双方签署64位促销 - 但为什么呢?

这两个可执行文件都编译为64位,这可以发挥作用吗?

1 回答

  • 12

    没有负整数常量 . 应用了一元 - 运算符只有正数 .

    2147483648 > INT_MAX 以来,在应用 - 之前,将 2147483648 提升为下一个较大的签名(因为您没有追加 u )整数类型 .


    顺便说一句,这就是 INT_MIN 通常在 <limits.h> 中被定义为 (-INT_MAX - 1) 的原因 . ;-)

相关问题