Building an Adder
Nobody taught the computer to add. Two gates per column, a carry travelling left, and arithmetic falls out of the wiring.
- Build the sum and carry of one column from an XOR and an AND gate
- Explain what the third input to a full adder is for
- Trace a carry across a multi-bit addition
- Explain overflow in terms of a carry with nowhere to go
Finish first
Topic contents
Lesson 1 of 3
Addition is not a feature, it is a shape
A calculator seems to know maths, but inside a processor there is no little person doing sums. There is only a pattern of gates whose output always matches what addition would give. The maths is not programmed in. It falls out of the wiring.
Look at one column of a binary addition. Two bits come in: 0 + 0, 0 + 1, 1 + 0 or 1 + 1. The sum bit is 1 when the inputs differ, which is XOR. A carry appears when both inputs are 1, which is AND. Two gates, and one column is solved.
That pairing is called a half adder. Open the lab and watch it happen. You are not memorising a formula. You are watching switches add.
4-bit ripple-carry adder
Add two numbers column by column, with the XOR and AND results shown for each column and the carry travelling left.
Binary adder
4-bit ripple carry · 2 gates per columnStart
Adding 6 and 3, which are 0110 and 0011. The circuit has no idea what those numbers mean. It works one column at a time from the right, using exactly two gates per column.
Lesson 2 of 3
The third input, and why half is not enough
A half adder handles the rightmost column and then fails, because every column after the first can receive a carry from its right. So a real column has three inputs, not two: the two bits being added and the carry coming in. That version is a full adder, and it is built from two half adders with their carries combined.
The rules stay just as simple. The sum bit is 1 when an odd number of the three inputs are 1, which is XOR applied twice. A carry leaves whenever at least two of the three inputs are 1, because two 1s in one column is worth exactly the next column's place value. Nothing here needs to count; it only needs to answer those two questions.
Set A to 6 and B to 3 in the lab and step through it column by column. Then try A as 7 and B as 1 and watch the carry travel through three columns before it finally lands. That travelling is real: each gate takes a moment to settle, and the settling times add up along the chain.
Lesson 3 of 3
Overflow, and the cost of the ripple
Chain four full adders together and you have a 4-bit ripple-carry adder, which is what the lab shows. Chain sixty-four and you have the integer adder in a real processor. The wiring does not change, only the length, and this is the pattern the whole field runs on: get one small unit exactly right, then repeat it.
Length has two consequences. First, the carry out of the last column has nowhere to go, so 15 + 1 in four bits produces 0 with a carry discarded. That is overflow, and it is the same silent wrap-around from the binary topic, now visible as a wire that leads nowhere. Press Show an overflow in the lab to watch it happen.
Second, the ripple costs time. Column three cannot finish until column two has settled, so a 64-bit ripple adder waits on 64 settling delays in the worst case. Real processors avoid this with cleverer carry circuits that predict carries instead of waiting for them, which is a genuinely harder idea, but it exists purely to solve the problem you just watched.
Worked examples
Read the code, then change it
Copy any example into the playground and break it on purpose. That is the fastest way to learn what each line is holding up.
const XOR = (a, b) => (a === b ? 0 : 1);
const AND = (a, b) => (a && b ? 1 : 0);
const OR = (a, b) => (a || b ? 1 : 0);
function fullAdder(a, b, carryIn) {
const half = XOR(a, b);
return {
sum: XOR(half, carryIn),
carryOut: OR(AND(a, b), AND(half, carryIn)),
};
}
function addBits(aBits, bBits) {
let carry = 0;
const sum = [];
for (let i = aBits.length - 1; i >= 0; i -= 1) {
const result = fullAdder(aBits[i], bBits[i], carry);
sum[i] = result.sum;
carry = result.carryOut;
console.log('column ' + 2 ** (aBits.length - 1 - i) + ': sum ' + result.sum + ', carry out ' + carry);
}
return { sum, overflow: carry === 1 };
}
console.log(addBits([0, 1, 1, 1], [0, 0, 0, 1])); // 7 + 1
console.log(addBits([1, 1, 1, 1], [0, 0, 0, 1])); // 15 + 1 overflowsPractice
Work these out yourself
No answer key here on purpose: these are the questions worth thinking through before you move on. Open one and work it out.
0/3 attemptedAssessment
Check your understanding
Answer each question, then read the explanation. That is where the learning is.
Finished this topic?
0 of 3 lessons marked done. Marking the topic complete ticks the rest.
