Boneyard Tools

How twos complement stores negative numbers

Why hardware picks twos complement over sign-and-magnitude, the invert-and-add-one trick, and how fixed-width wraparound causes overflow.

One scheme, no separate sign bit logic

Early designs tried sign-and-magnitude, where the top bit just marks the sign and the rest holds the size. That approach needs special handling for addition and even produces two versions of zero, a positive and a negative one. Twos complement avoids both problems by defining a negative number as its distance below a wraparound point. The same adder circuit that sums positives then handles negatives with no extra rules, which is exactly why nearly every processor made since the 1970s uses it.

The invert-and-add-one trick

To negate a number in twos complement you flip every bit and add one. Take 5 in 8 bits, which is 00000101. Inverting gives 11111010, and adding one gives 11111011, which is -5. The trick works because flipping all bits computes the ones complement, and adding one shifts it to the value that sums with the original to a clean power of two. This calculator does the same arithmetic internally by adding 2 to the power of the width to any negative input.

Fixed width means wraparound

Every result here is exactly as wide as the bit width you choose, and that fixed size is what makes overflow possible. In 8 bits the largest signed value is 127, stored as 01111111. Add one more and the pattern becomes 10000000, which reads back as -128, not 128. The number wrapped around the top of the range instead of growing, which is the same behavior that turns a runaway counter negative in real programs. Watching the binary column tick over the halfway point makes the effect concrete.

The same bits, two readings

A bit pattern carries no sign on its own; the sign only exists in how you agree to read it. The pattern 11111111 is 255 as an unsigned byte and -1 as a signed one, and the Unsigned column in this tool shows both readings side by side. That dual meaning is why casting between signed and unsigned types in C or Rust can flip a value dramatically even though not a single bit changed. Knowing which interpretation a variable uses is often the difference between a correct program and a subtle bug.

Frequently asked questions

Why does adding one to the largest positive give a negative?

The value range is fixed by the bit width, so incrementing past the maximum wraps around to the most negative value. In 8 bits, 127 plus one becomes -128 because the pattern rolls over to 10000000.

Is the sign bit just the leftmost digit?

The most significant bit does indicate sign in twos complement, but it also carries weight. It is not a separate flag; the whole pattern is interpreted together, which is why decoding subtracts 2 to the power of the width when that top bit is set.