无符号和有符号整数的比较操作 [英] Comparison operation on unsigned and signed integers

查看:297
本文介绍了无符号和有符号整数的比较操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

看到这段代码片段

  int main()
{
unsigned int a = 1000;
int b = -1;如果(a> b)printf(A is BIG!%d \ n,a-b),则
;
else printf(a is SMALL!%d \\\
,a-b);
返回0;
}

这给出了输出:a是SMALL:1001



我不明白这里发生了什么。 >运营商如何在这里工作?为什么a小于b?如果它确实更小,为什么我得到一个正数(1001)作为差异?

解决方案

不同整数类型之间的二元操作在由所谓的常规算术转换(请参阅语言规范,6.3.1.8)。在你的情况下,common类型是 unsigned int 。这意味着 int 操作数(您的 b )将被转换为 unsigned int

-1 是转换为 unsigned int 结果是可能的最大值 unsigned int 值(与 UINT_MAX )。不用说,它会比你的未签名的 1000 值大,这意味着 a>与(无符号)相比,b 确实是false,并且 a 确实小 code>。您的代码中的 if if 应该解析为 else 分支,这就是您在实验中观察到的结果。



相同的转换规则适用于减法。你的 ab 真的被解释为 a - (unsigned)b ,结果的类型为 unsigned INT 。由于%d 仅适用于 signed ,因此无法使用%d 格式说明符打印此值。 >值。用%d 打印它的尝试会导致未定义的行为,因此您看到的打印值(即使它在实践中有一个逻辑确定性的解释)完全没有意义C语言的观点。



编辑:其实,我可能对未定义的行为部分是错误的。根据C语言规范,相应有符号和无符号整数类型的范围的公共部分应具有相同的表示(根据脚注31,作为参数的可互换性)。因此,如上所述, a - b 表达式的结果是无符号 1001 ,除非我遗漏了某些东西,用%d 说明符打印这个特定的无符号值是合法的,因为它落在 int 的正范围内。使用%d 打印(无符号)INT_MAX + 1 将是未定义的,但 1001u 很好。


See this code snippet

int main()
{ 
 unsigned int a = 1000;
 int b = -1;
 if (a>b) printf("A is BIG! %d\n", a-b);
 else printf("a is SMALL! %d\n", a-b); 
 return 0;
}   

This gives the output: a is SMALL: 1001

I don't understand what's happening here. How does the > operator work here? Why is "a" smaller than "b"? If it is indeed smaller, why do i get a positive number (1001) as the difference?

解决方案

Binary operations between different integral types are performed within a "common" type defined by so called usual arithmetic conversions (see the language specification, 6.3.1.8). In your case the "common" type is unsigned int. This means that int operand (your b) will get converted to unsigned int before the comparison, as well as for the purpose of performing subtraction.

When -1 is converted to unsigned int the result is the maximal possible unsigned int value (same as UINT_MAX). Needless to say, it is going to be greater than your unsigned 1000 value, meaning that a > b is indeed false and a is indeed small compared to (unsigned) b. The if in your code should resolve to else branch, which is what you observed in your experiment.

The same conversion rules apply to subtraction. Your a-b is really interpreted as a - (unsigned) b and the result has type unsigned int. Such value cannot be printed with %d format specifier, since %d only works with signed values. Your attempt to print it with %d results in undefined behavior, so the value that you see printed (even though it has a logical deterministic explanation in practice) is completely meaningless from the point of view of C language.

Edit: Actually, I could be wrong about the undefined behavior part. According to C language specification, the common part of the range of the corresponding signed and unsigned integer type shall have identical representation (implying, according to the footnote 31, "interchangeability as arguments to functions"). So, the result of a - b expression is unsigned 1001 as described above, and unless I'm missing something, it is legal to print this specific unsigned value with %d specifier, since it falls within the positive range of int. Printing (unsigned) INT_MAX + 1 with %d would be undefined, but 1001u is fine.

这篇关于无符号和有符号整数的比较操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆