Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does signed to unsigned casting in C changes the bit values

Tags:

c

integer

casting

I've done some quick tests that a signed int to unsigned int cast in C does not change the bit values (on an online debugger).

What I want to know is whether it is guaranteed by a C standard or just the common (but not 100% sure) behaviour ?

like image 972
Guillaume Petitjean Avatar asked Jan 01 '23 14:01

Guillaume Petitjean


2 Answers

Conversion from signed int to unsigned int does not change the bit representation in two’s-complement C implementations, which are the most common, but will change the bit representation for negative numbers, including possible negative zeroes on one’s complement or sign-and-magnitude systems.

This is because the cast (unsigned int) a is not defined to retain the bits but the result is the positive remainder of dividing a by UINT_MAX + 1 (or as the C standard (C11 6.3.1.3p2) says,

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.

The two’s complement representation for negative numbers is the most commonly used representation for signed numbers exactly because it has this property of negative value n mapping to the same bit pattern as the mathematical value n + UINT_MAX + 1 – it makes it possible to use the same machine instruction for signed and unsigned addition, and the negative numbers will work because of wraparound.

like image 155

Casting from a signed to an unsigned integer is required to generate the correct arithmetic result (the same number), modulo the size of the unsigned integer, so to speak. That is, after

int i = anything;
unsigned int u = (unsigned int)i;

and on a machine with 32-bit ints, the requirement is that u is equal to i, modulo 232.

(We could also try to say that u receives the value i % 0x100000000, except it turns out that's not quite right, because the C rules say that when you divide a negative integer by a positive integer, you get a quotient rounded towards 0 and a negative remainder, which isn't the kind of modulus we want here.)

If i is 0 or positive, it's not hard to see that u will have the same bit pattern. If i is negative, and if you're on a 2's complement machine, it turns out the result is also guaranteed to have the same bit pattern. (I'd love to present a nice proof of that result here, but I don't have time just now to try to construct it.)

The vast majority of today's machines use 2's complement. But if you were on a 1's complement or sign/magnitude machine, I'm pretty sure the bit patterns would not always be the same.

So, bottom line, the sameness of the bit patterns is not guaranteed by the C Standard, but arises due to a combination of the C Standard's requirements, and the particulars of 2's complement arithmetic.

like image 44
Steve Summit Avatar answered Jan 12 '23 09:01

Steve Summit