The problem with negatives
Unsigned binary only counts upward: 8 bits give you 0–255. But programs need temperatures below zero, bank balances in the red, coordinates to the left of origin. You can't just stick a "−" in front — memory holds bits, not punctuation. The obvious fix is sign-magnitude: reserve the leftmost bit as a sign (0 = positive, 1 = negative) and read the rest as usual. So 00000101 is +5 and 10000101 is −5.
It works, but it's ugly. There are two zeros (+0 and −0), and the CPU needs separate, fiddly logic to add mixed-sign numbers. In the 1960s the industry converged on something better: two's complement, where the leftmost bit carries a negative place value instead of just being a sign flag.
How it works: invert and add one
To represent a negative number −N in 8-bit two's complement:
- Write
Nin binary: 5 →00000101 - Flip every bit (this is the "one's complement"):
11111010 - Add 1:
11111011
So 11111011 means −5. To read a negative value back, run the process in reverse (subtract 1, flip the bits) — or use the place-value trick: in two's complement the leftmost bit is worth negative its normal value. For 11111011: −128 + 64 + 32 + 16 + 8 + 0 + 2 + 1 = −5. ✓
Why it's brilliant: addition just works
Add 5 + (−5) with the ordinary binary adder circuit — no special negative-number logic at all:
00000101 (5)
+ 11111011 (−5)
-----------
100000000
The result is 9 bits; the overflow bit falls off the 8-bit register, leaving 00000000 — exactly 0. The hardware never knew negatives were involved. This is the whole reason two's complement won: one adder circuit handles everything, and there's only a single zero.
The range is asymmetric
With 8 bits there are 256 patterns. Half encode negatives, leaving 128 patterns for zero and positives:
| Width | Range | Min pattern | Max pattern |
|---|---|---|---|
| 8-bit | −128 … 127 | 10000000 | 01111111 |
| 16-bit | −32,768 … 32,767 | 1000…0000 | 0111…1111 |
| 32-bit | −2,147,483,648 … 2,147,483,647 | 1000…0000 | 0111…1111 |
The negative side always reaches one further than the positive side — that's why 32-bit signed integers max out at the famous 2,147,483,647. (The Y2K38 problem is just this limit applied to timestamps.)
How to spot a negative
Check the most significant bit (leftmost): 1 means negative, 0 means non-negative — if the value is interpreted as signed. The same bit pattern 11111011 is 251 unsigned but −5 signed. The bits don't carry the interpretation; the programmer (or the programming language's type) does. This signed/unsigned duality is a classic source of bugs — and of interview questions.
Try it yourself
Enter a binary number, enable signed mode, and see the two's complement value for 8, 16, 32 or 64 bits.
Key takeaways
- Two's complement encodes negatives by making the leftmost bit worth negative its place value.
- To negate: flip all bits and add 1.
- Addition, subtraction and multiplication need no special sign logic — the magic of the system.
- Ranges are asymmetric: 8-bit signed spans −128 to 127.
- The same bits mean different values signed vs unsigned — interpretation is everything.
Frequently asked questions
How do I compute the two's complement of a number?
Write the positive number in binary, flip every bit (0→1, 1→0), then add 1. For 5 (00000101): flipped is 11111010, plus 1 gives 11111011, which is −5 in 8-bit two's complement.
Why is the signed range asymmetric, like −128 to 127?
There are 256 possible 8-bit patterns. Half (128) represent negative numbers, and the other half cover zero plus 127 positives — so the negative side reaches one further: −128 to 127.
How can I tell if a binary number is negative?
Look at the leftmost bit (the most significant bit). In two's complement, 1 means negative and 0 means non-negative — but only if you know the value is meant to be signed.
Why did two's complement win over other methods?
Because addition just works. The same adder circuit handles positive and negative numbers with no special cases, and there is only one zero. Sign-magnitude needed extra logic and had both +0 and −0.