← Binary Course — Part C, lesson 3 of 5 (Negative numbers)

11. Two's Complement: The Trick, and Why It Actually Works

LESSON 11 | 0000 1011 | 0x0b

The concept

Lesson 9's sign-magnitude wasted a bit pattern on a second zero and needed a full compare-and-subtract algorithm for addition. Lesson 10's one's complement fixed addition down to a single rule — add the patterns, then fold any carry out of the top bit back in — but that end-around carry was still extra work, and the two-zeros problem never went away.

Two's complement fixes both at once, with one small change to how negation works: instead of just inverting every bit (Lesson 10), invert every bit and then add 1. That's the whole trick. It looks like a minor extra step tacked onto Lesson 10's method, but it's not cosmetic — it changes the actual magnitude bits, not just the sign, and that changes everything about how addition behaves.

Here's why the "add 1" matters so much. Lesson 10 built -k as "flip every bit of k," which is the same as (all-ones) - k. Two's complement instead builds -k as (all-ones) - k + 1 — one more than that — which is exactly 2^8 - k for an 8-bit word (256 - k). Now add some positive value m to that: m + (256 - k) = 256 + (m - k). Adding two 8-bit words can produce a 9th bit, a carry out of the top position — and here, that 9th bit is worth exactly 256. Discarding it (exactly the way ordinary 8-bit wraparound already discards any overflow, no special end-around step required) leaves precisely m - k — the correct answer, automatically, no matter which of m or k is bigger or what either one's sign is. The same "extra 1" that changes the magnitude bits also guarantees that a plain add-and-discard-the-overflow is already correct subtraction. It's also why real hardware overwhelmingly settled on two's complement: subtraction reduces to "invert and add," reusing the very same adder circuit addition already needs, with no separate sign-case logic at all.

Example 1 — Negating a value: invert, then add 1 — not just flip the sign

+5 in 8 bits: 0000 0101. A tempting shortcut, carried over from sign-magnitude habits, is to just flip the sign bit and leave the rest alone:

naive (wrong) guess:  1000 0101

That is not two's complement negation. The real method inverts every bit of the whole word, then adds 1:

invert 0000 0101  ->  1111 1010
add 1             ->  1111 1011

So -5 is 1111 1011 — nothing like the naive guess's magnitude bits. Decoding confirms it: reversing the same process (invert, then add 1) on 1111 1011 gives 0000 0101 = 5, so the word decodes to -5. Negating a two's-complement number changes far more than one bit; that's the core surprise this scheme trades in exchange for fixing addition and zero.

Example 2 — Only one zero

Negate 0 the same way:

invert 0000 0000  ->  1111 1111
add 1             ->  1 0000 0000   <- a 9th bit again

Discard that 9th bit exactly the way 8-bit addition already discards any overflow, and what's left is 0000 0000 — the same pattern as +0. Unlike Lessons 9 and 10, there is no second, wasted zero pattern. Two's complement has exactly one bit pattern for zero.

Example 3 — Addition needs nothing special at all

Add +5 and -3 (-3 is 1111 1101, by the invert-then-add-1 method):

0000 0101   (+5)
  • 1111 1101 (-3)

1 0000 0010 <- a 9th bit, discarded exactly like ordinary overflow

Discarding the 9th bit leaves 0000 0010 = +2 — correct (5 + (-3) = 2) — from one plain addition. No end-around carry to fold back in (Lesson 10), no comparing magnitudes and picking a sign (Lesson 9). Just add, and let any overflow fall off the top the same way it always has since Lesson 2.

Example 4 — The same plain rule, even for two negatives

Add -5 and -3 (1111 1011 and 1111 1101):

1111 1011   (-5)
  • 1111 1101 (-3)

1 1111 1000 <- a 9th bit, discarded the same way

Discarding the 9th bit leaves 1111 1000. Decoding it (invert, then add 1: 0000 0111 + 1 = 0000 1000 = 8) gives -8 — correct (-5 + (-3) = -8). Same rule, same one step, regardless of which operands are negative, positive, or which is larger. This is the payoff of Example 1's "add 1": every combination of signs now runs through identical hardware, with the correct answer falling out of discarding the overflow bit, never needing a special case.

Exercises

Exercise 1. Represent +19 and -19 in 8-bit two's complement, using invert-then-add-1.

Exercise 2. Give the 8-bit two's-complement pattern for -19 (from Exercise 1) in hex, using Lesson 3's nibble table. You now have -19 in hex under all three schemes this course has covered: 0x93 (sign-magnitude, Lesson 9), 0xec (one's complement, Lesson 10), and whatever you get here — three different bit patterns, same value, same width.

Exercise 3. A classmate, still thinking in sign-magnitude habits, negates +12 (0000 1100) by flipping only the sign bit: 1000 1100. Decoding that word as two's complement (invert, then add 1, to recover the magnitude), what value does it actually represent? How far off is that from the correct -12 — and what does the real invert-then-add-1 method give instead?

Show Answer Key

1. +19 = 0001 0011. Invert: 1110 1100. Add 1: -19 = 1110 1101.

2. 1110 1101, converted nibble by nibble (Lesson 3): 1110 → e, 1101 → d. -19 = 0xed in two's complement. Three schemes, three hex values (0x93, 0xec, 0xed) for the exact same number at the exact same width — the clearest possible demonstration that a bit pattern's meaning is never self-announcing; it depends entirely on which convention is reading it.

3. Decoding 1000 1100 as two's complement: invert it (0111 0011), add 1 (0111 0100 = 116), so the word decodes to -116 — wildly far from the intended -12, not just a little off. Flipping only the sign bit is not a shortcut for two's complement negation; it happens to work for sign-magnitude (Lesson 9) precisely because sign-magnitude keeps the sign and magnitude bits independent, and two's complement deliberately does not. The real method: invert 0000 1100 to get 1111 0011, add 1 to get 1111 0100 — the correct -12.

Two's complement fixes both of sign-magnitude's problems at once: one zero pattern, and addition that needs nothing beyond a single plain add with overflow discarded exactly the way unsigned addition already works. Lesson 12 builds on this directly — two's complement subtraction, and why it needs no separate subtract circuit beyond the adder addition already uses.