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.