I was running this little experiment on codepad.org, to understand what happens when negative numbers (using two's complement form) are assigned to unsigned integers. But the outcome is not as I expect. Perhaps you guys can shed some light on why.
1 2 3 4 5 6 7 8 9 10 11 12 13 14
unsignedshort u = 10, u2 = 42;
cout << "sizeof(unsigned short): " << sizeof(u) * 8 << " bits\n";
cout << u2 - u << endl;
cout << u - u2 << endl; // I expect this to produce 65504,
// but the result is -32.
I thought that the compiler would know because both operands are of the same type - and therefore assume that no casting/conversion is necessary.
If I run the same experiment with unsigned int, I get the expected result. The size of an unsigned int in my system is 4 bytes (32 bits) and the result from the u-u2 expression is 4294967264 (11111111111111111111111111100000 in binary), that is, unsigned. So in this case the code produces the result I had expected, but for unsigned short (16 bits) it seems to treat the result (1111111111100000 in binary) as a signed value. It's confusing to me.
The compiler performs the integral promotion on both operands of the additive operator -. That means that objects of types that have the rank less than the rank of the type int are converted to the type int. The rank of unsigned short is less than the rank of int so u and u2 are converted to int. After that the expression u - u2 is executed that also has type int because the both its operands have type int after the integral promotion.
Compare your code with the following code
1 2 3
unsignedint u = 10, u2 = 42;
std::cout << u - u2 << std::endl;
Here the both operands have the type unsigned int. The rank of unsigned int is not less than the rank of int. So the integral promotion will not be performed and you will get a positive number will be displayed on the console as the result of the operation.
I'm guessing this is a compiler/system specific peculiarity. Perhaps in a 64-bit system the operands would be converted to 64-bit values at calculation time, because the int type is represented by 64 bits in memory?
Thank you both for your teaching me something new today!