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
?
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.
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