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

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

问题描述

查看此代码片段

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

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

This gives the output: a is SMALL: 1001

我不明白这里发生了什么.> 运算符在这里如何工作?为什么a"比b"小?如果它确实更小,为什么我得到一个正数(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?

推荐答案

不同整数类型之间的二元运算在由所谓的普通算术转换定义的公共"类型内执行(请参阅语言规范, 6.3.1.8).在您的情况下,常见"类型是 unsigned int.这意味着 int 操作数(您的 b)将在比较之前转换为 unsigned int,以及用于执行减法的目的.

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.

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

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.

相同的转换规则适用于减法.您的 a-b 实际上被解释为 a - (unsigned) b 并且结果的类型为 unsigned int.这样的值不能用 %d 格式说明符打印,因为 %d 只适用于 signed 值.您尝试使用 %d 打印它会导致未定义的行为,因此从 C 语言的角度来看,您看到的打印值(即使它在实践中具有逻辑确定性解释)完全没有意义.

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.

实际上,我可能对未定义行为部分有误.根据 C 语言规范,相应的有符号和无符号整数类型的范围的公共部分应具有相同的表示(根据脚注 31,作为函数参数的可互换性").因此,如上所述,a - b 表达式的结果是无符号 1001,除非我遗漏了什么,否则使用 %d 说明符,因为它落在 int 的正数范围内.使用 %d 打印 (unsigned) INT_MAX + 1 将是未定义的,但 1001u 很好.

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天全站免登陆