int main() {
unsigned i = 5;
int j = -10;
double d = i + j;
long l = i + j;
int k = i + j;
std::cout << d << "\n"; //4.29497e+09
std::cout << l << "\n"; //4294967291
std::cout << k << "\n"; //-5
std::cout << i + j << "\n"; //4294967291
}
我认为在进行算术运算符之前,signed int
会被提升为unsigned
虽然-10
会转换为无符号unsigned integer underflow
(这是正确的术语?? ),但在添加后会打印4294967291
。
为什么在int k
打印-5
的情况下不会发生这种情况?
答案 0 :(得分:6)
执行算术运算符的过程涉及转换以使两个值具有相同的类型。此流程的名称是查找常用类型,对于int
和unsigned int
,转换名称为usual arithmetic conversions。在这种特殊情况下,不使用术语promotion。
如果是i + j
,int
将unsigned int
转换为UINT_MAX + 1
。因此,i + j
的结果为UINT_MAX - 4
,您系统上的结果为4294967291
。
然后将此值存储在各种数据类型中;唯一需要进一步解释的输出是k
。值UINT_MAX - 4
无法容纳int
。这称为超出范围的赋值,结果值是实现定义的。在您的系统上,它显然会分配int
值,该值与unsigned int
值具有相同的表示。
答案 1 :(得分:1)
j
将转换到unsigned int
,这会在您的所有i + j
中发生。快速实验。
在int k = i + j
的情况下。与您的实施和我的实施一样,i + j
生成:4294967291
。 4294967291
大于std::numeric_limits<int>::max()
,行为将由实现定义。为什么不尝试将4294967291
分配给int
?
#include <iostream>
int main(){
int k = 4294967291;
std::cout << k << std::endl;
}
产地:
-5
见Here