No more secrets Part 9: An adder can subtract, too

Da raspibo.
Jump to navigation Jump to search

Now we can add positive and negative numbers. Do we need a specific circuit to compute subtraction? The answer is again "almost no". All what we need is a circuit able to compute the ones' complement of a number, i.e. able to flip all the bit values of a number, all the zeros become ones and viceversa.

The trick is the following: if we add the minuend to the ones' complement of the subtrahend and we further add one, we get the difference.

We can see this from another point of view, if we add one to the one's complement of a number we get its opposite.

0100 is 4
1011 is the one's complement of 0100
adding one the result is:
1100 which is -4

1001 is -7
0110 is the one's complement of 1001
adding one the result is:
0111 which is 7

So, the 'trick' adds the opposite of the subtrahend to the minuend.

Not surprisingly the 'trick' works for both signed and unsigned numbers.

unsigned
 4 - 2 = 0100 - 0010 = 0100 + 1101 + 1 = (1)0010 = 2
10 - 3 = 1010 - 0011 = 1010 + 1100 + 1 = (1)0111 = 7
13 - 3 = 1101 - 0011 = 1101 + 0100 + 1 = (1)1010 = 10
signed
 4 - 2 = 0100 - 0010 = 0100 + 1101 + 1 = (1)0010 = 2
-3 - 3 = 1101 - 0011 = 1101 + 0100 + 1 = (1)1010 = -6
-3 -(-3) = 1101 - 1101 = 1101 + 0010 + 1 = (1)0000 = 0

In order to use a chain of full adders to compute substractions we need:

  • to supply the ones' complement of the second operand
  • to set the Cin of the MSB adder to one (this will be the extra 1 added

in to the one's complement).

If we set the input lines as just described, the output line provides the correct value of the difference.

The same circuit can be used to compare numbers, too. In fact if we subtract unsigned numbers, the result is meaningful only when the minuend is larger than the subtrahend. In this case the Cout of the MSB adder is one, otherwise it is zero. So, if we set up the circuit to compute the difference X - Y and we consider only the Cout of the MSB: Cout is 1 if X >= Y, Cout is 0 otherwise.

X=10 Y=3
10 - 3 = 1010 - 0011 = 1010 + 1100 + 1 = (1)0111 Cout is 1: 10 >= 3
10 - 10 = 1010 - 1010 = 1010 + 0101 + 1 = (1)0000 Cout is 1: 10 >= 10
3 - 10 = 0011 - 1010 = 0011 + 0101 + 1 = (0)1001 Cout is 0: 3 < 10
(the result, 9 is wrong, as 3 - 10 cannot be represented as unsigned number!)

It is possible to compare signed numbers too, but the situation is a bit more complex. In this case X < Y if the result of a XOR between the signed overflow and the value of the MSB of the result is one (the signed overflow itself is the result of a XOR between the Cout and the Cin of the MSB).

This definition gives the correct result even in case of overflow of the subtraction.

Maybe some examples can help to understand the rule:

A=4 B=6 unsigned: 0100 - 0110 = 0100 + 1001 + 1 = (0)1110
Cout=0 so A < B
A=4 B=6 signed 0100 - 0110 = 0100 + 1001 + 1 = (0)1110
                              100 +  001 + 1 = (0)110
overflow=0 MSB=1   Cout XOR MSB=1 so A<B

A=10 B=3 unsigned: 1010 - 0011 = 1010 + 1100 + 1 = (1)0111
Cout=1 so A >= B
A=-6 B=3 signed 1010 - 0110 = 1010 + 1100 + 1 = (1)0111
                               010 +  100 + 1 = (0)111
overflow=1 MSB=0   Cout XOR MSB=1 so A<B
Note that 10 as a signed 4 bit number and -6 as signed number have
the same representation.

A=12 B=14 unsigned: 1100 - 1110 = 1100 + 0001 + 1 = (0)1110
Cout=0 so A < B
A=-4 B=-2 signed: 1100 - 1110 = 1100 + 0001 + 1 = (0)1110
                                 100 +  001 + 1 = (0)110
overflow=0 MSB=1   Cout XOR MSB=1 so A<B

A=7 B=10 unsigned: 0110 - 1010 = 0110 + 0101 + 1 = (0)1100
Cout=0 so A < B
A=7 B=-6 signed: 0110 - 1010 = 0110 + 0101 + 1 = (0)1100
                                110 +  101 + 1 = (1)100
overflow=1 MSB=1   Cout XOR MSB=0 so A>=B