Represent negative numbers in binary

When we are starting to work with binary numbers we are always introduced with a little table that shows us the first decimal numbers in binary, but then, how would it look the table of the first negative numbers?

The answer here is that it depends on who’s interpreting the data, finally, binary numbers can have a lot of different meanings depending on how we are reading it, for example, 4 is interpreted as 100 but if we just pass a sequence of one thousand of this data to another person without indicating who’s the MSB bit, the quantity of bits or if the data has signed or not, they will have a long time struggling and testing if our dataset makes sense or not.

Gladly most computer systems use a standard to manage negative numbers called two’s complement, what’s this about?

First, let’s talk about one’s complement, this was a process to work with negative numbers in which all we have to do is flip all the numbers we have, let’s put as an example the number 8 which in binary is represented as 1000.

Before one's complement = 0000 1000
After one's complement = 1111 0111

Now to pass from one’s complement to two’s complement all we have to do is add one to the previous result

Before adding 1 = 1111 0111
After adding 1 = 1111 1000

This is perfect now we have our two’s complement representation of 8 in a 8 bit system, just to have in mind:

2's complement = 1's complement + 1

Let’s note that in two’s complement the MSB is our sign, so instead of having the possibility to represent till 255 with our 8 bits we can represent from -128 to 127, we are gonna have 1 bit for the sign and 7 bits to represent information both negative and positive, let’s put a little c code example:

#include <stdio.h>


int main()
{
char A = 0b00001010;
char B = 0b00000101;
int result = A + B;
printf("%d\n", result);
return (0);
}

Here we are adding A (10) and B (5) if we execute this code we get that the result is:

But let’s now do what we want, let’s change A from 10 to -10 by using the two’s complement logic

#include <stdio.h>
int main()
{
char A = 0b00001010;
char B = 0b00000101;
A = ~A + 1; /* Converts 10 to -10 */
int result = A + B;
printf("%d\n", result);
return (0);
}

The c bitwise operator not (~) will flip all the bits for us, after that, all we have to do is just add one to the result.

Why is C understanding this? basically because or data type is signed char, so c understand that we are reserving our MSB bit for the sign and the rest for data. if we use the datatype unsigned:

#include <stdio.h>
int main()
{
unsigned char A = 0b00001010;
unsigned char B = 0b00000101;
A = ~A + 1;
int result = A + B;
printf("%d\n", result);
return (0);
}

If we execute the code:

Wow a big number, that’s because here we don’t have a bit that represents the sign and the following process occurs:

One complement -> 1111 0101
Plus one (Two's complement) -> 1111 0110
//Adding A + B
1111 0110 + -> 246
0000 0101 -> 5
---------
1 0000 0000 -> 251

So… two’s complement is the only way to represent a negative binary number? there’s also the sign and magnitude method in which you, just add the sign bit as MSB but don’t take the two’s complement, what’s wrong about it?

First, you are going to have two representations of 0: — 0 and + 0, not too good for the performance business, also when doing operations with integers if we have a final carry we cannot threat it like a normal bit, so you have to apply more logice for a simple add, while in two’s complement the sign is part of the add and you don’t have the double 0 problems. Sign and magnitude is good for humans to be interpreted but not efficient for machine building.

--

--

David Alexander Orejuela Caicedo
How to represent negative numbers in binary?

Embedded Software Developer interested in creating new technology with maximum performance and amazing features, C, VHDL and python lover.