Casting a negative int to a bigger unsigned int in C

Viewed 97
int main(){
 int a = -33553454;
 unsigned long b = a;
 return 0;
}

In the above example, a is first sign extend to a 64 bit value as a signed integer (meaning 1's will be placed on its left side), and the value is then assigned to b as an unsigned int.

Is it safe to say that, only the type of the original source operand matters (if its signed or unsigned) and the destination type is not taken into account in this case (since the destination is unsigned, you would think a would not get sign extended because the end result is unsigned anyways, and 0s would fill the left side of b. )

1 Answers

You're converting an int value to an unsigned long value. How this happens is dictated by section 6.3.1.3 of the C standard:

1 When a value with integer type is converted to another integer type other than _Bool, if the value can be represented by the new type, it is unchanged.

2 Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.

3 Otherwise, the new type is signed and the value cannot be represented in it; either the result is implementation-defined or an implementation-defined signal is raised

Paragraph 2 is what applies in this case. Because the value in question is negative and therefore out of the range of an unsigned long, the largest value for that type +1 is added to the original value to get the new value.

So assuming the maximum value for unsigned long is 264-1 (or 18446744073709551615) the value -33553454 (0xFE0003D2) is converted to 18446744073709551616 - 33553454 = 18446744073675998162 (0xFFFFFFFFFE0003D2). You'll notice that if your machine uses two's complement representation (which most do) that the representation of these numbers happens to be the same (after sign extension).

Related