为什么是一个大于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 int
是4294967292
,远远大于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。
这告诉我int
与unsigned 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。 在这种情况下( int
和unsigned int
) int
值将首先转换为unsigned int
。
其次,C中的无符号整数运算以该types的最大值+1(即“循环”,所以UINT_MAX + 1
再次为0
,反之亦然)进行模数。 因此,将负值转换为无符号结果的数量非常大。
标准中的相关部分说:
6.3.1.3有符号和无符号整数
2
否则,如果新types是无符号的,则通过重复地增加或减去新types中能够表示的最大值之一来转换该值,直到该值在新types的范围内。
当你比较一个int
和一个unsigned int
, int
被转换为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。