← Binary Course — Part C, lesson 2 of 5 (Negative numbers)
10. One's Complement, Briefly, and Why It Was Mostly Abandoned
The concept
Lesson 9 left sign-magnitude with two problems: a wasted, ambiguous zero, and an addition rule that needed a full compare-the-magnitudes-and- subtract algorithm because the sign bit was never anything more than an ordinary bit tacked on the side — plain addition had no way to know it was special.
One's complement changes how negation itself works, and that one change fixes the addition problem almost completely. Instead of flipping only the sign bit, negate a number by flipping every bit — the bitwise NOT from Lesson 5, applied to the whole word. That single change means addition can go back to being one mechanical rule for every combination of signs: add the two 8-bit patterns as plain unsigned numbers, and if that addition produces a carry out of the top bit, don't throw it away — fold it back in by adding it to the bottom bit. This is called an end-around carry. No comparing magnitudes, no deciding which operand to subtract from which — just add, then check for a carry to fold back in.
What one's complement does not fix is the other problem. NOT-ing zero
still produces a second bit pattern — this is exactly Lesson 5's
A + NOT A = all-ones identity applied to A = 0, and it means
"negative zero" is still a distinct, wasted pattern sitting alongside
"positive zero." Combined with the fact that the end-around carry is
itself an extra step real adder hardware has to implement, most machines
that considered one's complement moved past it. Lesson 11 covers what
they moved to: two's complement, which fixes both problems at once.
Example 1 — Negating a value: flip every bit, not just the sign
+5 and -5 in 8-bit one's complement:
+5: 0000 0101
-5: 1111 1010 (bitwise NOT of 0000 0101, per Lesson 5)
Contrast with Lesson 9: sign-magnitude negation flips one bit and leaves
the rest untouched; one's complement flips all eight. Decoding a
negative one's-complement word reverses the process — if the sign bit is
1, NOT the whole word to recover the magnitude. NOT(1111 1010) = 0000 0101 = 5, so 1111 1010 decodes to -5.
Example 2 — Two zeros, still
+0 and -0:
+0: 0000 0000
-0: 1111 1111 (bitwise NOT of 0000 0000)
This is Lesson 5's A + NOT A = all-ones identity, applied to the case
A = 0: NOT-ing an all-zero word can only ever produce an all-one word.
Switching from sign-magnitude to one's complement doesn't remove the
two-zeros problem from Lesson 9 — it just relocates the second, wasted
zero pattern from 1000 0000 to 1111 1111.
Example 3 — Addition: one mechanical rule for every sign combination
Add +5 and -3 the same "just add the patterns" way that broke for
sign-magnitude in Lesson 9 Example 4:
0000 0101 (+5)
- 1111 1100 (-3, from NOT of 0000 0011)
1 0000 0001 <- a 9th bit: a carry out of bit 7
Ordinary 8-bit wraparound would discard that 9th bit. One's complement addition doesn't — it folds the carry back in by adding it to the bottom bit:
0000 0001
-
1
0000 0010 (+2) <- correct: 5 + (-3) = 2
Not every case produces a carry to fold back in. Add +3 and -5:
0000 0011 (+3)
- 1111 1010 (-5, from NOT of 0000 0101)
1111 1101 (no carry out of bit 7 this time)
No carry was produced, so there's nothing to fold back in — the plain
sum is already the answer. Decoding it (sign bit 1, so NOT the whole
word to recover the magnitude: NOT(1111 1101) = 0000 0010 = 2) gives
-2, which is correct: 3 + (-5) = -2.
The same rule handled both cases — add the patterns, then fold in a carry out of the top bit if (and only if) one occurs. Unlike Lesson 9's algorithm, nothing here branches on which operand is larger or which sign is which.
Exercises
Exercise 1. Represent +19 and -19 in 8-bit one's complement.
Exercise 2. Give the 8-bit one's-complement pattern for -19 (from
Exercise 1) in hex, using Lesson 3's nibble table. Compare it with
Lesson 9's answer for sign-magnitude -19's hex — same value, same
width, different bit pattern.
Exercise 3. A classmate adds +6 and -4 in one's complement —
0000 0110 + 1111 1011 — but forgets the end-around-carry step: they
add the two patterns, get a 9-bit result, and just drop the 9th bit the
way ordinary wraparound would, without folding it back in. What word do
they end up with, and what does it decode to? Is that a plausible-looking
answer, or an obviously broken one? What's the actual correct result,
and what step did they skip to get there?
Show Answer Key
1. Magnitude of 19 in 8 bits: 0001 0011 (same as its unsigned/
sign-magnitude form — positive values look identical across all three
schemes). -19 is its bitwise NOT: NOT(0001 0011) = 1110 1100.
2. 1110 1100, converted nibble by nibble (Lesson 3): 1110 → e,
1100 → c. -19 = 0xec in one's complement — different from Lesson 9's
0x93 for sign-magnitude -19, even though both represent the same
value at the same width. Confirms Lesson 9's closing point: a bit
pattern's meaning depends on which convention is reading it.
3. 0000 0110 + 1111 1011 = 1 0000 0001 (9 bits): a carry out of bit
7. Dropping that carry the way plain wraparound would gives 0000 0001,
which decodes (sign bit 0) to +1 — a small, perfectly plausible-
looking positive number, not an obviously broken one, which is exactly
what makes forgetting the end-around carry an easy mistake to miss.
Folding the dropped carry back into the bottom bit instead — `0000 0001
- 1 = 0000 0010
— gives the actual correct result,+2, matching6 + (-4) = 2`. The skipped step was the end-around carry itself: a carry out of the top bit was produced and then discarded instead of being added back in.
One's complement fixed addition's compare-and-subtract awkwardness almost entirely — a single add-then-fold-in-the-carry rule replaces Lesson 9's two-branch algorithm — but the end-around carry is still extra work plain unsigned addition never needed, and the two-zeros problem never went away. Lesson 11 introduces two's complement, the scheme that fixes both problems at once: no end-around carry, and only one bit pattern for zero.
Sign in to mark lessons complete and keep your progress.