Subtraction
Gate-Level CPU Simulator
To compute in two's complement, you negate and then add. Negation in two's complement is two operations: invert every bit (a row of NOT gates) and add 1. The "+1" you can fold directly into the ripple-carry adder by setting its bit-0 carry-in to 1 instead of 0. So a subtractor is just a ripple-carry adder with NOTs on the inputs and a cin of 1.
def ripple_subtract(A, B):
"""Compute A - B for n-bit two's-complement numbers.
Negate B by inverting and adding 1."""
Bn = [NOT(b) for b in B]
n = len(A)
result = []
carry = 1 # the "+1" of two's complement
for i in range(n):
s, carry = full_adder(A[i], Bn[i], carry)
result.append(s)
return result # discard the final carry
Even better: a single "add/subtract" unit takes one extra control
bit, sub. When sub = 1, XOR-gate every
bit of with 1 (which inverts it) and feed
sub as the cin. When sub = 0, the XORs
pass through unchanged and cin is 0. One circuit,
both operations. The control unit drives sub.
Worked example: compute in 4-bit two's complement.
Encode ; invert to 1100; add 1 to
get 1101 (which is the two's-complement encoding of
). Then add: .
Discard the final carry — the bottom 4 bits are 0100 = 4,
which is . The full-adder did the arithmetic;
NOTs on and a cin of 1 turned it into a subtractor
without any new gates.