Integers in a CPU are represented using a fixed number of binary digits. For example, 64 expressed in binary using eight bits is 01000000
.
Generally, negative numbers are expressed in two's complement. To get the two's complement of a binary number, you first compute the one's complement of the positive number (which means, flip all the bits), then add one.
For example, to calculate the two's complement of -64, start with 64 in binary:
01000000 then flip all the bits to get one's complement
10111111 then add one, ignoring the final carry (i.e. overflow)
11000000
11000000
is C0
in hex.
The same process can be carried out using 16-bits:
00000000 01000000 (64)
11111111 10111111 (one's complement of 64)
11111111 11000000 (one's complement of 64 plus one)
11111111 11000000
in hex is FFC0
.
The reason two's complement is used for negative numbers is because it eliminates special cases. A negative number and a positive number can be added together normally, and the right answer will result. For example, -1 in 8-bit two's complement is 11111111
. Adding one to that correctly gives back zero (11111111
+ 00000001
= 00000000
), since there are not enough bits to hold the carry.