我知道积分转换可能非常棘手,并且应用不同整数类型的操作数可能会破坏例如<
运算符:
std::cout << (-1 < 1u)
false
甚至是==
运营商:
std::cout << (4294967295u == -1)
true
(尽管如此,上述两个例子都会产生警告)
我想知道的是:
==
运算符进行比较,并且任一操作数的值位于另一个操作数的范围内,我是否可以确定如果语句的计算结果为true
,则值为真的相等吗?==
运营商在什么情况下会产生合理的结果?如何使用它来比较有符号和无符号值而不出错?答案 0 :(得分:3)
- 如果我将两个操作数与
==
运算符进行比较,并且任一操作数的值位于另一个操作数的范围内,我是否可以确定如果语句的计算结果为true
,则值为真的相等吗?
是即可。只要满足两个条件:
但是:这并不意味着这是一个好主意。编译器警告不应掉以轻心。
对于大多数二元运算符(包括==
)和整数操作数,编译器将首先对每个操作数应用整数提升(C ++ 11:§4.5[conv.prom])独立。这会将操作数转换为至少unsigned int
或(最好)int
。这会保留操作数的所有可能值,但它可以将一种类型从无符号值更改为更大的有符号值。
接下来,编译器查找公共类型(C ++ 11:§5[expr] / 9)。此类型不会大于两个操作数中的较大者。这里确实可以改变值:可能会发生签名类型转换为无符号类型,在这种情况下,负值不会延续。但由于我们排除了负值,因此这不是问题。
答案 1 :(得分:0)
在无符号和有符号数字之间进行比较时始终处于类似情况 操作将在2个无符号数之间。
在这种情况下
(-1 < 1u)
-1 = 0b11111111111111111111111 (1* 32 times)=4294967295u
1u = 0b00000000000000000000001
所以很清楚这是错误的,因为
4294967295u = 0b11111111111111111111111
你不能代表4294967295不在unsigned int。
你可以看到
-1==4294967295u
一般来说,在这种情况下,一些编译器会给你警告,但你必须小心..