Two's complement and negative numbers
The two’s complement by itself isn’t too difficult to understand, but it is not immediately obvious why the two’s complement is used to represent negative numbers. The truth is, computer engineers of old could have chosen any of a variety of ways to represent negative numbers, but the two’s complement was the most computationally efficient. In this post, we’ll explore both the two’s complement and other ways negatives could have been represented. By the end, it will be clear why we use the two’s complement.
The most simple possible scheme would be to use one bit to represent the sign - say 0 for positive and 1 for negative. If we did that, then the number 0010 and 1010 would mean +2 (0 = positive, 010 = 2) and -2 (1 = negative, 010 = 2). But if we tried to add those numbers using the normal process, we would get 0010 + 1010 = 1100. That says +2 + -2 = -4! (1 = negative, 100 = 3) The normal addition rules do not work with this simple scheme.
Rather than design new rules for doing math, early computer designers figured out a slightly different way to represent signed numbers called two’s complement notation. In this scheme, the first bit indicates sign - 0 for positive and 1 for negative. Positive numbers are treated as normal. So 0100 still means 4.
A number that starts with 1 is negative. Its value is defined by the following rule: take the other bits and flip them (0s become 1s and 1s become 0s) then add one to the value they represent. Thus 1011 would be interpreted as negative because of the leading 1, then we would take the other bits 011 and flip each one to get 100, 100 is 4, we add one to that to get 5, so 1011 means -5.
Two’s Complement Interpretation
- A leading 0 means positive - read the number normally.
- A leading 1 means negative - flip the remaining bits, read their value and one to the value. Make that value negative.
We can use this same idea with more than 4 bits. We always just use the first bit as the sign and the rest of the bits as the value and use the same rules for negative numbers. Thus the 8-bit two’s complement number 11011000 would mean: first bit is 1, so negative, flip the last seven bits to 0100111, that is 39 (32 + 4 + 2 + 1), add one to get 40, so the value is -40.
Advantages of Two's Complement
The main advantage of two’s complement is that the normal rules for addition work with it as long as we ignore extra bits. Say we have:
0110 +1110
That means 6 + (-2). If we add them using the normal rules we would get:
111 (Carries) 0110 (6) +1110 (-2) 10100
Since we started with 4 bits, we should only keep the last four bits of the answer: 0100 or 4. That means 6 + (-2) = 4.
It also works for two negative numbers. Here is -2 + (-2):
111 (Carries) 1110 (-2) +1110 (-2) 11100
Take only the last 4 bits and we get 1100. The leading 1 means negative. So flip the last three bits from 100 to 011. That means 3. Add one and get 4. So -2 + (-2) = -4.
It is also easy to find the inverse of a number. To turn a negative into a positive or vice verse, invert all the bits and add one. If there is a carry past the last digit, ignore it.
Two’s Complement Conversion
To change the sign of a number, flip all the bits and add one. Ignore any carry past last original digit.
For example, here is converting 5 to -5:
0101 (+5)
1010 (flip bits)
1010 (now add one)
+ 1
1011 (-5)
And from -5 back to 5:
1011 (-5)
0100 (flip bits)
0100 (now add one)
+ 1
0101 (+5)
Overflow
Remember that overflow is when a value becomes too large to store in the bits we have. With two’s complement, an overflow with a large positive value can produce a negative answer. For example, say I am working with 4-bit two’s complement numbers. The largest positive number we can write in two’s complement with four bits is 0111 or 7. Now say I add 5 + 5 (0101 + 0101):
1 1 (Carries)
0101 (5)
+0101 (5)
1010 (-6 in two's complement)
As an unsigned number, 1010 would mean ten. But in two’s complement that means -6! The same thing can happen with negative numbers - if a negative number becomes too small it can wrap around to positive numbers!
Normally integers are stored as 32-bit values. This gives a range of approximately +2.147 billion to -2.147 billion - usually enough to hold our answers. But if your math problem involves an answer that is too big you can “wrap around”. Below I have added code to make your web browser try to display the answer to some math problems. The answers to both are wrong as we are overflowing and wrapping from + to - or vice verse:
2,000,000,000 * 2 = -294967296
(Should be 4,000,000,000 but we wrapped around to negative.)
-2,000,000,000 + -500,000,000 = 1794967296
(Should be -2,500,000,000 but we wrapped back around to positive.)