为什么 0x1 被解释为小于 0xC0000000?

Why is 0x1 interpreted as less than 0xC0000000?

我正在学习整数的二进制表示,并尝试编写一个 returns 和 int 使用饱和度乘以 2 的函数。思路是如果值正向溢出函数returnsINT_MAX,反之如果负向溢出则returnsINT_MIN。在所有其他情况下,二进制值左移 1。

我想知道的是,为什么我必须将值 0xC0000000 转换为 int,以便在传递参数 x = 1 时让我的函数正常工作。

这是我的函数:

int timestwo (int x){
    if(x >= 0x40000000) // INT_MAX/2 + 1
        return 0x7fffffff; // INT_MAX
    else if(x < (int) 0xC0000000) // INT_MIN/2
        return 0x80000000; // INT_MIN
    else
        return x << 1;
    return 0;
}

C 中的十六进制(和八进制)文字使用最小的提升类型(=int 或更高级别的类型)类型,有符号或无符号,可以容纳该值。 这不同于十进制文字,如果它们没有 u/U 后缀,则保留在有符号类型中,否则在无符号类型中 (6.4.4.1p5):

这使得 0xC0000000 在具有 32 位整数的系统上无符号和比较(或通过运算符配对)无符号与相同级别的有符号强制有符号变为无符号(6.3.1.8),所以如果没有 (int) 强制转换,你会得到一个隐含的 (unsigned int)x < (unsigned int) 0xC0000000

常量0xC0000000指定的值不适合int(假设32位),但它适合unsigned int,所以这个常量的类型是 unsigned int。此无符号值大于 1,因此比较结果为假。

转换为 int 的结果实际上是实现定义的,尽管在二进制补码系统中这通常会产生您所期望的结果。