Sign-Magnitude, One's Complement and Two's Complement
How integer numbers are stored in computer memory — and how the three binary encoding schemes differ.
How a byte looks in memory
Numbers in computer memory are stored in binary form. The byte type in Java is 8 bits wide. Each bit holds either 0 or 1:
In signed integers, the leftmost (most significant) bit is the sign bit: 0 means positive, 1 means negative. The remaining 7 bits encode the magnitude. This foundation is shared by all three encoding schemes.
Sign-magnitude
The most intuitive encoding. The sign bit indicates direction, and the remaining 7 bits store the exact binary magnitude of the number.
| Decimal | Sign-magnitude (8 bits) |
|---|---|
| 3 | 0 000 0011 |
| 2 | 0 000 0010 |
| 1 | 0 000 0001 |
| 0 | 0 000 0000 |
| −0 | 1 000 0000 |
| −1 | 1 000 0001 |
| −2 | 1 000 0010 |
0 000 0000 (+0) and 1 000 0000 (−0). Arithmetic circuits must handle this as a special case, which makes hardware more complex. Modern CPUs use two's complement instead.One's complement
To negate a number in one's complement, you invert every single bit — including the sign bit. No bit is excluded.
One's complement still has the two-zeros problem. 1 111 1111 represents −0, distinct from +0 (0 000 0000). Two's complement solves this.
Two's complement
This is how Java (and virtually every modern CPU) stores negative integers. It eliminates double-zero and makes addition and subtraction the same hardware operation regardless of sign.
Converting a positive number to its two's complement negative
Invert all bits — including the sign bit (this gives the one's complement):
Add 1 to the result:
1111 1100. Check: 1111 1100 + 0000 0100 = 0000 0000 (overflow discarded) ✓Full comparison table
| Decimal | Sign-magnitude | One's complement | Two's complement |
|---|---|---|---|
| 0 | 0 000 0000 | 0 000 0000 | 0 000 0000 |
| −0 | 1 000 0000 | 1 111 1111 | — (no −0) |
| −1 | 1 000 0001 | 1 111 1110 | 1 111 1111 |
| −2 | 1 000 0010 | 1 111 1101 | 1 111 1110 |
| −3 | 1 000 0011 | 1 111 1100 | 1 111 1101 |
| −4 | 1 000 0100 | 1 111 1011 | 1 111 1100 |
| −5 | 1 000 0101 | 1 111 1010 | 1 111 1011 |
Integer ranges in Java
All four Java integer primitives use two's complement. The asymmetry (one extra negative) is a direct consequence of eliminating −0.