Integer promotion unsigned in c++

2020-07-22 10:11发布

问题:

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
}

I believe signed int is promoted to unsigned before doing the arithmetic operators.
While -10 is converted to unsigned unsigned integer underflow (is this the correct term??) will occur and after addition it prints 4294967291.

Why this is not happening in the case of int k which print -5?

回答1:

The process of doing the arithmetic operator involves a conversion to make the two values have the same type. The name for this process is finding the common type, and for the case of int and unsigned int, the conversions are called usual arithmetic conversions. The term promotion is not used in this particular case.

In the case of i + j, the int is converted to unsigned int, by adding UINT_MAX + 1 to it. So the result of i + j is UINT_MAX - 4, which on your system is 4294967291.

You then store this value in various data types; the only output that needs further explanation is k. The value UINT_MAX - 4 cannot fit in int. This is called out-of-range assignment and the resulting value is implementation-defined. On your system it apparently assigns the int value which has the same representation as the unsigned int value.



回答2:

j will be converted to unsigned int before addition, and this happens in all your i + j. A quick experiment.

In the case of int k = i + j. As in the case of your implementation and mine, i + j produces: 4294967291. 4294967291 is larger than std::numeric_limits<int>::max(), the behavior is going to be implementation defined. Why not try assigning 4294967291 to an int?

#include <iostream>

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

Produces:

-5

As seen Here