所以:
unsigned int u = 10; signed int s = -8; std::cout << s + u << std::endl; //prints 2 because it will convert `s` to `unsigned int`,now `s` has the value //4294967288,then it will add `u` to it,which is an out-of-range value,so,//in my machine,`4294967298 % 4294967296 = 2`
我不明白 – 我读到,如果有符号的操作数的类型大于无符号的操作数:
>如果无符号类型中的所有值都适合较大的类型,则将无符号操作数转换为带符号的类型
>如果无符号类型中的值不适合较大的类型,则带符号的操作数将被转换为无符号类型
所以在下面的代码中:
signed long long s = -8; unsigned int u = 10; std::cout << s + u << std::endl;
你会转换为签名long long,因为int值可以符合签名的long long?
如果是这种情况,在什么情况下较小的类型值将不适合较大的类型值?
解决方法
5表达式[expr]
10 Many binary operators that expect operands of arithmetic or
enumeration type cause conversions and yield result types in a similar
way. The purpose is to yield a common type,which is also the type of
the result. This pattern is called the usual arithmetic conversions,
which are defined as follows:
[关于等同类型或类似等号的条款被省略]
— Otherwise,if the operand that has unsigned integer type has rank
greater than or equal to the rank of the type of the other operand,
the operand with signed integer type shall be converted to the type of
the operand with unsigned integer type.— Otherwise,if the type of
the operand with signed integer type can represent all of the values
of the type of the operand with unsigned integer type,the operand
with unsigned integer type shall be converted to the type of the
operand with signed integer type.— Otherwise,both operands shall be
converted to the unsigned integer type corresponding to the type of
the operand with signed integer type.
让我们考虑以下3个上述条款中的每一个的例子,其中sizeof(int)< sizeof(long)== sizeof(long long)(容易适应其他情况)
#include <iostream> signed int s1 = -4; unsigned int u1 = 2; signed long int s2 = -4; unsigned int u2 = 2; signed long long int s3 = -4; unsigned long int u3 = 2; int main() { std::cout << (s1 + u1) << "\n"; // 4294967294 std::cout << (s2 + u2) << "\n"; // -2 std::cout << (s3 + u3) << "\n"; // 18446744073709551614 }
第一个子句:等级的类型,所以有符号的int操作数被转换为unsigned int.这需要一个值变换(使用二进制补码)给出打印值.
第二个子句:签名类型具有较高的等级,并且(在该平台上!)可以表示无符号类型的所有值,因此无符号操作数转换为签名类型,您得到-2
第三个子句:签名类型再次具有较高的等级,但是(在这个平台上!)不能表示无符号类型的所有值,所以两个操作数都被转换为无符号long long,并且在经过符号操作数的值转换之后,印刷价值.
注意,当无符号操作数足够大时(例如在这些示例中为6),则由于无符号整数溢出,所有3个示例的最终结果将给出2.
(已添加)请注意,当您对这些类型进行比较时,您会获得更多意想不到的结果.让我们考虑上面的例子1<
#include <iostream> signed int s1 = -4; unsigned int u1 = 2; int main() { std::cout << (s1 < u1 ? "s1 < u1" : "s1 !< u1") << "\n"; // "s1 !< u1" std::cout << (-4 < 2u ? "-4 < 2u" : "-4 !< 2u") << "\n"; // "-4 !< 2u" }
由于2u由u后缀显式未被分配,因此适用相同的规则.结果可能不是你期望的,当比较-4当写入C -4 < 2U ...