What are complements ?
Complements are way to store negative numbers and manipulate them in binary.
Why complements ?
Representing negative numbers in binary was a real hassle ! That’s were complements help to store signed numbers as binary.
But it was not always like that.
1. Sign-Magnitude
First idea of representing signs:
0
= +
and 1
= -
, followed by the number in binary !
00000101 = 5
10000101 = -5
❌ Problem with sign-magnitude
- Two representation of
0
->00000000
(+0
) and10000000
(-0
) . - Calculation difficult for the CPU !
int a = +0;
int b = -0;
// ambigious, depends on compiler.
// Even though this prints "Equal", internally +0 and -0 may be stored differently,
// which makes operations more complex and ambiguous at the binary level.
if(a == b){
std::cout << "Equal" << std::endl;
}
Two values of 0 will cause issue because if the compiler considers signed then its not equal else they are equal. So there must be 256 unique values.
So 1’s Complement came in…
2. 1’s Complement
1’s Complement said rather than using a sign bit we flip the whole number to get its negative !
00000101
= 5
11111010
= -5
We flip the bits ! We get the negative part ! But this was also not the best solution
❌Problem with 1’s Complement
1’s Complement had the same issues.
- Similar 0 values !
- Harder arithmetic for CPU to perform.
00000000
= +0
11111111
= -0
But 2’s complement solves this issue
3. 2’s Complement
This new complement method just solves the issue the others weren’t able to do ! 2’s complement adds 1 to the 1’s complement of a number to get its negative.
00000101
= 5
11111010
= ~5 (1’s complement)
11111011
= -5 (2’s complement) (Needed Negative Number as binary)
How is it working ?
So the logic is the range ! 2’s complement is for signed integers therefore it ranges from -128
to +127
.
The MSB acts as a negative weight (−128
in 8-bit
systems) — it’s not just a flag but part of the actual value. For example:
2’s Complement for 5 to get -5 :
00000101
= 5;
11111011
= -5 (2’s Complement)
1 1 1 1 1 0 1 1 #<-(-5)
-128 + 64 + 32 + 16 + 8 + 0 + 2 + 1 = -5
If the first bit is 0
then its a positive Number !
IT LOOKS LIKE BLACK MAGIC !
💡 How it solves dual 0 representation
Lets just look at representation for 0:
00000000
: 0
11111111
: -1 (This was -0
for 1’s complement and sign-magnitude)
Key observation:
If the first bit is -128
won’t we encounter +128
and have the same issue ?
🤔 Isn’t there a clash when we arrive at a mirrored value ?
Yes there would have been a clash…but…there is no +128
in 2’s Complement as the bit required to get +128
is reserved by -128
so the highest we can get to is +127
i.e. 64 + 32 + 16 + 8 + 4 + 2 + 1
(7 bits) and the MSB is 0
if its 1
then it becomes -128
therefore we will have -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1
which is -1
!
This is how computers store signed numbers, Both Positives and Negatives !