2017-02-13 56 views
2
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在C++中无符号整型促销

为什么在int k打印-5的情况下不会发生这种情况?

回答

6

执行算术运算符的过程涉及转换以使两个值具有相同的类型。该过程的名称是找到常见类型,对于intunsigned 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

j转换unsigned int此外面前,这种情况发生在你所有的i + j。快速实验。

int k = i + j的情况下。正如您的实施和我的情况一样,i + j产生:42949672914294967291大于std::numeric_limits<int>::max(),该行为将被实现定义。为什么不尝试将4294967291分配给int

#include <iostream> 

int main(){ 
    int k = 4294967291; 
    std::cout << k << std::endl; 
} 

产地:

-5 

如所见Here