-
Notifications
You must be signed in to change notification settings - Fork 326
Casting Signed to Unsigned in C
Someone had asked earlier if assigning from signed to unsigned just took the absolute value. The answer, generally speaking, is, "no, it does weird things".
In C, C++, and Go (and probably a pile of other languages), converting from signed to unsigned basically does the following, according to spec:
while (number < 0) {
number += MAX_UNSIGNED_INT + 1
}
This looks really weird (WHY would they do this??!!), but what's actually happening is a little bit simpler.
Deep down, the computer represents numbers as bits in sequential bytes. Using something called 2's complement representation, signed numbers are stored like so (using a 4-bit number for the sake of example simplicity--but it could be 64 bits, or whatever):
Signed:
binary 0001 = decimal 1 signed
binary 0000 = decimal 0
binary 1111 = decimal -1
binary 1110 = decimal -2
But compare that to how unsigned numbers are stored:
binary 0001 = decimal 1 unsigned
binary 0000 = decimal 0
binary 1111 = decimal 15
binary 1110 = decimal 14
The bit pattern for 15 is the same as the bit pattern for -1. When you convert from signed to unsigned, all it does is change how it's interprets the exact same bit pattern.
binary 1111
== signed decimal -1
== unsigned decimal 15
That means on a 4-bit machine, converting -1 to unsigned gives you 15.
On a 32-bit machine, converting -1 to unsigned gives 4294967295, which is binary 11111111111111111111111111111111 in both cases.