Binary has no minus sign. Every negative number in every computer is therefore a convention, an agreement about how to read plain bits as values below zero, and the convention that won is called two’s complement. It won for a beautifully practical reason: it lets the same circuit that adds also subtract, with no special cases. This guide builds the idea from one weighted bit, with our free negative binary decoder and encoder to test every example against.
In this guide
The problem: a sign with no symbol
The obvious fix, using the top bit as a pure sign flag (sign-magnitude), was tried and abandoned for two faults. It creates two zeros, 0000 0000 and 1000 0000 both meaning nothing, which doubles every equality check. Worse, ordinary addition stops working: adding +5 and a sign-magnitude −5 does not give zero, so the hardware would need separate circuitry deciding when to really add and when to secretly subtract. A representation that breaks the adder defeats the point of having one. The winning idea keeps the adder sacred and changes the reading instead.
The idea: one bit with negative weight
In an 8-bit two’s complement number, the place values are the familiar 64, 32, 16, 8, 4, 2, 1, except the top place, which is worth minus 128. Read 1111 1011 with those weights: −128 + 64 + 32 + 16 + 8 + 2 + 1 = −5. One negative weight, everything else unchanged, and the whole system follows: a number is negative exactly when its top bit is set (the only place a minus can come from), zero is unique, and values climb in unbroken order from −128 up through −1 (1111 1111, all weights firing) to 0, then 1 to 127. Paste 11111011 into the decoder and watch it read −5 with exactly this arithmetic.
The recipe: invert and add one
Nobody sums weights in practice; the working recipe is two steps. To negate any value: flip every bit, then add 1. From +5: 0000 0101 inverts to 1111 1010, plus one is 1111 1011, the −5 from above. The same recipe runs backwards: given a number that starts with 1, invert and add one to find its magnitude. The encoder performs the forward trip from any decimal, and for the positive half of the world, plain decimal to binary conversion covered in the binary-decimal guide is all you need. Why invert-plus-one works is one line of algebra: flipping all bits of x gives 255 − x (in 8 bits), so adding 1 gives 256 − x, and 256 − x behaves exactly like −x in a world where 256 wraps to zero, which is the next section.
Why it won: subtraction for free
Eight-bit arithmetic is odometer arithmetic: results wrap at 256. Two’s complement exploits that wrap so subtraction becomes addition: to compute 200 − 60, encode −60 (1100 0100, which reads 196 unsigned), add it to 200, and the sum 396 wraps past 256 to land on 140, the right answer, produced by the plain adder with no concept of subtraction at all. That is the entire victory: one adder circuit handles signed, unsigned, addition and subtraction identically, and the only thing that changes is how humans read the result. The reading really is the only difference: 1000 0000 is 128 to unsigned eyes and −128 to signed eyes, the same bits, two contracts, which is why mixing signed and unsigned types in code produces the famous “impossible” comparisons.
Ranges, the asymmetry, and overflow
| Width | Minimum | Maximum |
|---|---|---|
| 8-bit | −128 | 127 |
| 16-bit | −32,768 | 32,767 |
| 32-bit | −2,147,483,648 | 2,147,483,647 |
The ranges are lopsided by exactly one because zero lives in the positive half’s slot: 128 negative values, zero, and 127 positives fill the 256 patterns. The asymmetry has a sharp edge: negating −128 in 8 bits has no answer, since +128 does not fit, and invert-plus-one dutifully returns −128 itself. The wrap has a sharper one: 127 + 1 = −128, the overflow where one step past the maximum lands at the minimum, source of a long catalog of real bugs in counters, timers and scores that ran for longer than their width allowed. The defense is unglamorous: know the width, know the range, and treat values drifting near the boundary as the warning they are. The wider story of bases and bit patterns continues in the number systems pillar.
Frequently asked questions
Why is it called “two’s complement”?
Because negation replaces x with 2n − x, the complement with respect to a power of two: in 8 bits, −x is stored as 256 − x. The older “one’s complement” used 255 − x, plain bit inversion, and inherited the two-zeros problem that the extra +1 elegantly removes.
How do I know whether 1111 1011 means −5 or 251?
You cannot know from the bits; the type decides. Declared signed, it reads −5; declared unsigned, 251. Every language with fixed-width integers carries that contract in its types, and the decoder tools show both readings precisely because the bits alone refuse to say.
Does two’s complement apply to numbers with decimal points?
Not directly: floating-point formats store sign, exponent and fraction separately, an entirely different convention with a literal sign bit. Two’s complement governs integers, which is also where its overflow behavior lives; floats fail differently.
What happens when an 8-bit value moves to 16 bits?
It is sign-extended: the top bit is copied into all the new positions, so 1111 1011 (−5) becomes 1111 1111 1111 1011, still −5. Copying zeros instead would turn every negative into a large positive, which is exactly the bug that appears when code casts unsigned where it meant signed.