为什么是一个大于unsigned int的负int?

int main(void) { unsigned int y = 10; int x = – 4; if (x > y) Printf("x is greater"); else Printf("y is greater"); getch(); return (0); } Output: x is greater 

我认为输出将是更大,因为它是无符号的。 这背后的原因是什么?

因为int值被提升为unsigned int 。 特别是在32位机器上的0xFFFFFFFC ,作为unsigned int4294967292 ,远远大于10

C99 6.3.1.1-p2

如果int可以表示原始types的所有值(由宽度限制,对于位域),则该值被转换为int; 否则,它被转换为一个无符号的整数 。 这些被称为整数促销。 所有其他types均不受整数升级的影响。

要执行转换:

C99 6.3.1.3-p2

否则,如果新types是无符号的,则通过重复地增加或减去新types中能够表示的最大值之一来转换该值,直到该值在新types的范围内。

这基本上意味着“添加UINT_MAX + 1”(正如我读过的那样)。

关于为什么晋升为unsigned int方; 优先级:

C99 6.3.1.8-p1

…否则,如果具有无符号整数types的操作数具有大于或等于另一操作数types的等级,则具有有符号整数types的操作数被转换为具有无符号整数types的操作数的types。

否则,如果具有有符号整数types的操作数的types可以表示具有无符号整数types的操作数types的所有值,则将具有无符号整数types的操作数转换为具有有符号整数types的操作数的types。

这告诉我intunsigned char应该按预期工作。

testing

 int main() { int x = -4; unsigned int y = 10; unsigned char z = 10; if (x > y) printf("x>y\n"); else printf("x<y\n"); if (x > z) printf("x>z\n"); else printf("x<z\n"); return 0; } 

产量

 x>y x<z 

那么看看那个。

有符号和无符号值之间的比较将在“无符号空间”中进行。 即,通过添加UINT_MAX + 1将有符号的值转换为无符号。 在使用二值补码实现负值的情况下,不需要对值进行特殊处理。

在这个例子中, -4变成了一个0x100000000-4 = 0xFFFFFFFC ,显然是> 10

当你比较C中的两个值时,它们都必须是相同的types。 在这种情况下( intunsigned intint值将首先转换为unsigned int

其次,C中的无符号整数运算以该types的最大值+1(即“循环”,所以UINT_MAX + 1再次为0 ,反之亦然)进行模数。 因此,将负值转换为无符号结果的数量非常大。

标准中的相关部分说:

6.3.1.3有符号和无符号整数

2
否则,如果新types是无符号的,则通过重复地增加或减去新types中能够表示的最大值之一来转换该值,直到该值在新types的范围内。

当你比较一个int和一个unsigned intint被转换为unsigned int 。 将int转换为unsigned int是通过添加UINT_MAX+1 (请注意, int是负数)。 所以实际上你是在比较:

 if (-3 + UINT_MAX > 10) //Since -4 is converted to UINT_MAX+1-4 

这是真的

int值的第一位用于定义它是正还是负。 (1 =负数,0为正数)在比较之前,您的两个variables都被转换为无符号整数,第一位中的1将被解释为数字的一部分。

这段代码应该能正常工作:

 int main(void) { unsigned int y = 10; int x = – 4; if (x > (int) y) Printf("x is greater"); else Printf ("y is greater"); getch ( ); return (0); } 

int x = -4(4的2的补码是1111 1100 = 252),unsigned int y = 10是(0000 1010 = 10)所以252> 10所以-​​4大于10。