In this article, we dive into the topic of two’s complement number representation and try to explain how it works. We’ll work through it together, as I also need to check and validate my own understanding.
In a computer, numbers are represented in binary notation, as a sequence of bits. Since we need to work with negative numbers as well as positive ones, we need a system to represent the sign.
Two’s complement is a method to encode the sign information. Two’s complement is used by Java to represent integer numbers. For example, a Java language int is a 32-bit signed integer in the range of [-231, 231 – 1].
Why this range? We’ll get to that in a moment. But first, let’s look at numbers whose representation uses only the largest digit in a base.
In decimal, 9 is the largest digit. 9 = 10 – 1, 99 = 102 – 1, 999 = 103 – 1 and so forth.
In binary, 11 = 22 – 1, 1111 = 24 – 1.
In hexadecimal, F = 161 – 1 and FF = 162 – 1.
To conclude, in a base b, a number written by repeating the largest digit n times is equal to bn – 1.
To get the next largest number, we write 1 and turn all the other digits into zeros, effectively obtaining bn.
For example, FF16 + 1 = 10016 = 162
In two’s complement notation, the leftmost bit is reserved for the sign. By convention, it has a negative value.
Take the 32-bit number:
1_111111111111111111111111111111111111111
Can you guess what number it is?
The 31 bits to the right of the sign bit encode the number 231 – 1, as explained. The sign bit is equal to -231. Adding them up we obtain -1.
-231 + 231 – 1 = -1
We can verify this easily, using binary to hex conversion.
System.out.println(0xffffffff == -1); // true
If…
11111111111111111111111111111111
is -1, then…
10000000000000000000000000000000
is the minimum value of int, right?
System.out.println(0x80000000 == Integer.MIN_VALUE); // true
Also, zero followed by 31 set bits should be the maximum value of int.
System.out.println(0x7fffffff == Integer.MAX_VALUE); // true
Well, that explains why [-231, 231-1] is the range of a 32-bit signed two’s complement integer.
Another thing we can do is to revert the sign, in order to find a number’s complement. To find the complement of a number x, we take 231 – x.
For ex., to find the representation of the number -15, we take 231 – 15.
10000000000000000000000000000000 - 00000000000000000000000000001111 = 11111111111111111111111111110001
Indeed, in Java, 0xfffffff1
maps to -15.