How Computers Store Negative Numbers: Sign-Magnitude vs One’s vs Two’s Complement
Binary digits are just 0s and 1s — there is no minus sign. To store a negative number you have to encode the sign into the bits themselves,
and over the years three schemes were used: sign-magnitude, one’s complement, and two’s complement.
Two’s complement won — it has a single zero and lets a CPU subtract using the same adder it uses to add. This guide walks all three with one consistent
4-bit and 8-bit example, then sends the bit patterns to the
Two’s Complement Calculator.
The problem: no minus sign
A byte is just a row of bits — eight cells that each hold 0 or 1. Nothing in there is a "−". So to represent a negative integer we dedicate the
most-significant bit (MSB) — the leftmost one — as the sign bit: 0 means positive, 1 means negative.
The interesting question is what the remaining bits mean once you have decided the sign. Three historic answers exist, and they disagree on exactly how a negative value is laid out.
Sign-magnitude
The simplest idea: the MSB is the sign, and the remaining bits are the plain unsigned magnitude. So in 4 bits:
+5 = 0101— sign bit 0, magnitude101= 5.−5 = 1101— sign bit 1, same magnitude101= 5.
The range for n bits is symmetric: −(2^(n−1) − 1) … +(2^(n−1) − 1), which for 8 bits is −127 … +127.
Two problems sink it. First, there are two zeros: 0000 is +0 and 1000 is −0 — the same numeric value with two bit patterns, wasting a code and forcing equality checks to handle both.
Second, addition has to special-case the sign (you have to inspect the sign bits and decide whether to add or subtract magnitudes), which is awkward in hardware.
One’s complement
One’s complement keeps the MSB as the sign but defines negation as flipping every bit (a bitwise NOT). Starting from +5 = 0101, invert each bit:
+5 = 0101−5 = 1010— every bit of0101flipped.
The range is the same as sign-magnitude: −127 … +127 for 8 bits. And it still has two zeros — 0000 (+0) and 1111 (−0),
since flipping all the zeros gives all ones. Addition is closer to "normal" than sign-magnitude, but a carry off the top must be wrapped back around (the end-around carry),
and the duplicate zero remains. Almost there, but not quite.
Two’s complement (the winner)
Two’s complement makes one tiny change to one’s complement that fixes everything: to negate, flip all the bits AND add 1 (invert, then +1). Worked through in 4 bits:
+5 = 0101- invert →
1010 - add 1 →
1011= −5
The operation is its own inverse, so negating −5 gives back +5: invert 1011 → 0100, add 1 → 0101 = +5.
Three properties make this the encoding every modern CPU uses — they are the whole point:
- Exactly one zero. There is a single
0000; the old "−0" pattern is freed up and reused as an extra negative value. That makes the range asymmetric:−(2^(n−1)) … +(2^(n−1) − 1). For 8 bits that is −128 … +127; for 4 bits it is −8 … +7. - Subtraction is just addition. Because
−bis a real bit pattern you can add,a − b = a + (−b)runs through the same binary adder with no special sign-handling hardware. This single fact is why two’s complement is the universal choice — see it directly in the Binary Add / Subtract Calculator. - The MSB has negative place-value. The sign bit still reads as the sign, but mathematically it carries weight
−2^(n−1). In 8 bits,1111_1111evaluates as−128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = −1, so0xFF = −1. Likewise1000_0000 = −128and0111_1111 = +127.
Side-by-side comparison
The same set of 4-bit values under all three encodings. Note that −0 exists only in sign-magnitude and one’s complement (two’s complement has a single zero), and the most-negative value −8 exists only in two’s complement:
| Value (4-bit) | Sign-magnitude | One’s complement | Two’s complement |
|---|---|---|---|
| +5 | 0101 | 0101 | 0101 |
| −5 | 1101 | 1010 | 1011 |
| +0 | 0000 | 0000 | 0000 |
| −0 | 1000 | 1111 | — none — |
| −8 (most negative) | — n/a — | — n/a — | 1000 |
| +7 (most positive) | 0111 | 0111 | 0111 |
⚠️ Read the table carefully: −5 is 1101 in sign-magnitude, 1010 in one’s complement, but 1011 in two’s complement.
Same number, three different bit patterns — which is exactly why you must know which encoding you are looking at before decoding a raw byte.
Negating & reading by hand
To negate a two’s-complement number: invert every bit and add 1. To read a negative two’s-complement value you have two reliable options:
- Reverse the process: if the MSB is 1, invert-and-add-1 to get the magnitude, then prepend the minus sign. e.g.
1011→ invert0100→ +10101= 5, so1011 = −5. - Negative-MSB place-value sum: add up the place values, but count the MSB as negative. e.g. 8-bit
1111_1111 = −128 + 64 + … + 1 = −1.
You rarely need to do this by hand twice. The Two’s Complement Calculator converts in either direction for any bit width, the Number Base Converter shows the underlying bit pattern (and how the same bits read as unsigned vs signed), and the Binary Add / Subtract Calculator demonstrates that subtraction is just addition of the complement. For the conversion mechanics between bases, the sibling guide Binary, Hex & Decimal Conversion walks the nibble trick.
In practice: signed char & 0xFF
This is not academic. In C, a signed char is an 8-bit two’s-complement integer, so it runs −128…+127. Increment +127 (0111_1111) and it wraps to
1000_0000 = −128 — the classic signed overflow. And one byte, 1111_1111, prints as 255 when interpreted unsigned but −1 when interpreted as signed
two’s complement: same bits, two interpretations. Whenever you see a value flip from a large positive to a negative (or 0xFF showing up as −1), this encoding is the reason.
FAQ
- Why do computers use two’s complement?
- Two’s complement has exactly one representation of zero (0000), which avoids the wasted "−0" pattern that both sign-magnitude and one’s complement carry. Even better, subtraction becomes ordinary addition: a − b is computed as a + (−b) using the same binary adder, with no special-case hardware for signs. That is why every modern CPU uses it for signed integers. You can watch this play out in the Binary Add / Subtract Calculator, which performs a subtraction as the addition of a complement.
- How do I find the two’s complement of a number?
- Take the binary pattern, invert every bit (turn each 0 into a 1 and each 1 into a 0), then add 1. For example, 4-bit +5 is 0101; invert to 1010, add 1 to get 1011, which is −5. The process is its own inverse, so applying it again to 1011 gives back 0101 (+5). The Two’s Complement Calculator does this instantly for any bit width, and the Number Base Converter shows you the resulting bit pattern.
- What is the range of a signed 8-bit (two’s complement) number?
- A signed 8-bit two’s-complement value runs from −128 to +127. Because there is only one zero (0000_0000), one extra bit pattern is freed up on the negative side, making the range asymmetric: 1000_0000 is −128, 0111_1111 is +127, and 1111_1111 is −1. In general n bits cover −(2^(n−1)) up to +(2^(n−1) − 1).
- What’s the difference between one’s and two’s complement?
- One’s complement negates a number by inverting every bit only, while two’s complement inverts the bits and then adds 1. One’s complement keeps two zeros (0000 for +0 and 1111 for −0) and needs an end-around carry when adding, so its range is symmetric (−127…+127 for 8-bit). Two’s complement collapses that to a single zero, giving the extra negative value (−128…+127 for 8-bit) and letting subtraction reuse the adder. That single difference — the "+1" — is why two’s complement won.