Eight-bit two's complement example showing positive 5 converted to negative 5 by inverting the bits and adding one

What Is Two's Complement? How Signed Binary Numbers Work

By ProURLMonitor Team

Two's complement is a fixed-width binary format used to represent signed integers — numbers that can be positive, negative, or zero — in a set number of bits. Positive values are written as ordinary binary, padded out to the chosen width. Negative values are written so that ordinary binary addition, applied to that same fixed width, produces correct results whether the operands are positive or negative. Bit width matters throughout: the same sequence of bits can mean different things depending on how many bits you're told to read and whether you're reading it as signed or unsigned.

What Is Two's Complement?

Two's complement is the standard way computers encode signed integers in a fixed number of bits, N. Every possible value is one of 2N bit patterns, and each pattern has exactly one interpretation once N is fixed.

In an 8-bit two's-complement interpretation:

  • 0 to 127 are stored as their ordinary binary representation (00000000 to 01111111).
  • -1 to -128 are stored as bit patterns that begin with 1 (11111111 down to 10000000).

The bit that happens to be leftmost — the most significant bit, or MSB — is 1 for every negative value in this scheme and 0 for every non-negative value. That's a useful shorthand, but it isn't a separate "sign flag" bolted onto a magnitude. The next section explains why that distinction matters.

Two's complement also has exactly one bit pattern for zero (00000000 in 8-bit), unlike some older signed-number schemes. That single detail simplifies both circuit design and everyday reasoning about equality checks. (For a primer on why computers represent everything in binary in the first place, see Why Do Computers Use Binary?.)

How Two's Complement Represents Negative Numbers

Rather than treating the MSB as an independent minus sign, an n-bit two's-complement interpretation assigns it a real place value: -2(n-1). Every other bit keeps its usual positive power-of-two weight. For 8 bits, the weights from left to right are:

-128, 64, 32, 16, 8, 4, 2, 1

To decode any pattern, add up the weights of the bits that are 1. Take 11010110:

Bit:     1     1    0    1   0   1   1   0
Weight: -128   64   32   16  8   4   2   1

-128 + 64 + 16 + 4 + 2 = -42

That single weighted sum is the entire decoding rule — there's no separate "flip the sign, then read the rest as magnitude" step required, though that shortcut also works and is covered below.

How to Find Two's Complement

To find the two's complement of a negative decimal value at a fixed bit width, follow three steps:

  1. Write the absolute value in ordinary binary, padded to the chosen width.
  2. Invert every bit (this step alone is called the one's complement).
  3. Add 1 to the result, keeping the answer within the chosen width.

Worked example: -5 in 8-bit two's complement

+5 in 8-bit binary:      00000101
Invert every bit:        11111010
Add 1:                   11111011

Result: -5 in 8-bit two's complement = 11111011

This procedure only makes sense once a bit width is chosen — "the two's complement of 5" is meaningless without also specifying how many bits you're working in, since the inversion step depends on knowing exactly how many bits to invert.

For quick conversions at 4, 8, 16, 32, or 64-bit widths — in either direction — use the Two's Complement Calculator, which computes exact results with arbitrary-precision integers rather than relying on JavaScript's limited native number types.

Decoding a Two's-Complement Bit Pattern

Decoding works the same way in reverse. Given 11111011 as an 8-bit two's-complement value:

Invert every bit:        00000100
Add 1:                   00000101   → magnitude = 5

Since the original MSB was 1, the value is negative: -5

There's also a direct mathematical shortcut: read the bits as an ordinary unsigned number, then subtract 2n if the MSB is 1.

11111011 read as unsigned 8-bit = 251
251 - 256 = -5

Both methods agree because two's complement negation is arithmetic modulo 2n: for an 8-bit width, there are 256 possible patterns, and -5 is defined as the pattern for 256 - 5 = 251, which is 11111011. Thinking of it this way — negative values as "wrapping around" from the top of the range — makes the invert-and-add-one shortcut feel less like a memorized trick and more like a direct consequence of modular arithmetic.

Two's Complement Examples

Every row below is 8-bit two's complement, verified programmatically:

Decimal8-bit Two's Complement
000000000
100000001
500000101
1000001010
4200101010
12701111111
-111111111
-511111011
-1011110110
-4211010110
-12810000000

Why Does Bit Width Matter?

A binary pattern has no fixed signed meaning on its own — its interpretation depends entirely on the declared bit width and on whether it's being read as signed or unsigned at all. Consider -1:

-1 in 8-bit two's complement:   11111111
-1 in 16-bit two's complement:  1111111111111111

Both represent the same value, -1, but they are different bit patterns because they're different widths. Widening a positive value is simple zero-padding — +5 in 8-bit (00000101) becomes +5 in 16-bit (0000000000000101) by adding leading zeros. Negative values can't be widened the same way, because padding with zeros would change a negative value into a large positive one. Instead, widening a signed value requires sign extension: repeating the existing sign bit into every new leading position.

-5 in 8-bit:   11111011
-5 in 16-bit:  1111111111111011   (eight extra 1s prepended, not zeros)

This is also why the same 8 bits can mean two different things depending on signedness, not just width. 11111111 is -1 if read as signed 8-bit two's complement, but 255 if read as plain unsigned 8-bit binary — for how unsigned binary values map to decimal in general, see Binary vs Decimal. Any accurate description of a binary value has to specify both the width and whether it's signed.

Two's Complement Range

For an n-bit two's-complement integer, the valid range is:

Minimum: -2^(n-1)
Maximum:  2^(n-1) - 1
BitsMinimumMaximum
8-128127
16-32,76832,767
32-2,147,483,6482,147,483,647
64-9,223,372,036,854,775,8089,223,372,036,854,775,807

Why is the negative range one value larger than the positive range? An n-bit width has exactly 2n possible bit patterns — 256 for 8-bit. Two's complement spends exactly one of those patterns on zero (00000000), leaving 2n - 1 patterns to split between positive and negative values. For 8-bit: 127 patterns represent 1 through 127, and the remaining 128 patterns represent -1 through -128. Zero "borrows" a slot that would otherwise belong to the positive side, which is why the minimum, -128, has no positive counterpart at the same width — +128 simply isn't one of the 256 available 8-bit patterns.

One's Complement vs Two's Complement

One's complement is an earlier, related scheme for signed binary numbers. It negates a value by inverting every bit — no add-1 step.

One's ComplementTwo's Complement
Negation ruleInvert all bitsInvert all bits, then add 1
Zero representationsTwo: 00000000 (+0) and 11111111 (-0)One: 00000000
8-bit range-127 to 127-128 to 127
ArithmeticRequires an "end-around carry" correctionOrdinary fixed-width addition works directly

Having two bit patterns for zero is one's complement's biggest practical drawback: every equality check against zero has to account for both patterns, and arithmetic circuits need extra correction logic to handle the end-around carry. Two's complement avoids both problems, which is the main reason it displaced one's complement in essentially all modern hardware.

Two's Complement vs. Sign-Magnitude

Sign-magnitude is a third scheme: it reserves the MSB purely as a plus/minus flag and stores the rest of the bits as an ordinary magnitude. Like one's complement, it has separate positive and negative zero patterns and needs dedicated logic to inspect the sign bit before adding or subtracting. Two's complement avoids that special-casing entirely — the throughline across all three schemes is that two's complement wins on arithmetic simplicity and a single zero representation.

Why Is Two's Complement Used?

A few concrete properties explain why two's complement became the near-universal standard for signed integers on real processors:

  • One representation of zero. No separate positive/negative zero to special-case in comparisons.
  • Shared addition circuitry. Subtraction becomes addition of a negated value, so a processor's adder can handle positive and negative operands without a separate subtraction path or sign-checking logic in between.
  • Straightforward sign extension. Widening a value to more bits is just repeating the existing sign bit, with no reinterpretation of the magnitude bits required.
  • Consistent, predictable overflow behavior. Because arithmetic is defined modulo 2n, the wraparound behavior at the edges of the range is well-defined rather than dependent on ad hoc sign-handling rules.

None of this means two's complement is the only representation a computer could use — sign-magnitude and one's complement are both historically real alternatives — but the combination of a single zero and shared arithmetic circuitry made two's complement the practical winner.

Two's Complement Arithmetic

Because two's complement is designed around ordinary fixed-width addition, adding a positive and a negative number works without any special sign logic. Take 5 + (-3) in 8 bits:

   5:  00000101
  -3:  11111101
  -------------
 sum:  100000010   (9 bits — the leading 1 is a carry out of the 8-bit width)

Discard the carry beyond 8 bits: 00000010 = 2

The carry bit that falls outside the fixed 8-bit width is simply discarded, and the remaining 8 bits give the mathematically correct answer, 2 — no special handling was needed because one operand was negative. For general binary addition, subtraction, multiplication, and division on unsigned values, see the Binary Calculator; for AND, OR, XOR, and shift operations on raw bit patterns, see Bitwise Operations.

Overflow

Ordinary carry-out (as in the example above) is expected and harmless. Signed overflow is different: it happens when the true mathematical result falls outside the representable range for the bit width, so the wrapped bit pattern no longer means what it should. Take 127 + 1 in 8 bits:

 127:  01111111
  +1:  00000001
  -------------
 sum:  10000000

Read as signed 8-bit two's complement, 10000000 is -128 — not the mathematically correct +128, which doesn't fit in the 8-bit signed range at all. The bit pattern wraps around rather than raising an error on its own; detecting that this particular wrap is invalid requires separate overflow-detection logic (typically comparing the carry into and out of the sign bit), not just looking at the result.

The Minimum-Value Edge Case

The most representable negative value has no positive counterpart at the same width, which makes negating it a special case. In 8-bit two's complement, -128 is 10000000. Running the usual invert-and-add-one procedure on it:

10000000  (invert)  01111111  (add 1)  10000000

The result is the same bit pattern you started with, still representing -128 — not +128, which would require a 9th bit to store. Negating the minimum representable value in a fixed width is the one case where "invert the bits and add 1" doesn't produce the value you'd naively expect, precisely because the positive counterpart doesn't exist in that width.

Signed vs. Unsigned: Same Bits, Different Meaning

Bits in memory don't carry their own signedness — software decides how to interpret them. 11111111 is a single, unambiguous sequence of eight bits, but its decimal meaning depends entirely on the declared interpretation:

11111111 as unsigned 8-bit binary:              255
11111111 as signed 8-bit two's complement:       -1

Both readings are "correct" in the sense that the bits never change — only the rule used to translate them into decimal changes. This is why programming languages distinguish signed and unsigned integer types even though both are ultimately stored as ordinary bit sequences: the type tells the compiler, and anyone reading the code, which interpretation applies.

Common Mistakes

  • Skipping the bit width. "The two's complement of 20" is incomplete — the width has to be specified before the bit pattern means anything.
  • Treating the MSB as an independent minus sign. It's a bit with real place value, -2(n-1), not a flag layered on top of a separate magnitude.
  • Inverting bits but forgetting to add 1. That produces one's complement, not two's complement — a different value with a different range.
  • Reading a signed pattern as unsigned (or vice versa). The same bits decode to different decimal values depending on which interpretation is declared.
  • Ignoring overflow. A wrapped bit pattern is still a valid-looking pattern; nothing about it visibly signals that the true result didn't fit.
  • Assuming -128 has a +128 counterpart in 8-bit signed range. It doesn't — 127 is the maximum.
  • Zero-padding a negative value instead of sign-extending it. Padding a negative pattern with leading zeros turns it into a large positive number; widening it correctly requires repeating the sign bit instead.

Frequently Asked Questions

What is two's complement? Two's complement is a fixed-width binary format for representing signed (positive and negative) integers. Positive values are written as ordinary binary padded to the chosen width. Negative values are represented as their complement modulo 2^n, where n is the bit width, which lets ordinary binary addition handle both positive and negative numbers without special-case logic.

How do you find the two's complement of a binary number? Pick a bit width, write the number's magnitude in binary at that width, invert every bit, then add 1. For example, +5 in 8-bit binary is 00000101; inverting gives 11111010, and adding 1 gives 11111011, which is -5 in 8-bit two's complement.

Why is two's complement used? It gives every value exactly one bit pattern for zero, lets addition and subtraction share the same circuitry regardless of operand sign, and makes sign extension a simple matter of repeating the sign bit. That combination is why nearly all modern processors use two's complement for signed integers.

What is the range of an 8-bit two's-complement number? An 8-bit two's-complement integer ranges from -128 to 127. In general, an n-bit two's-complement integer ranges from -2^(n-1) to 2^(n-1) - 1: -32,768 to 32,767 for 16-bit, -2,147,483,648 to 2,147,483,647 for 32-bit, and -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807 for 64-bit.

What is the difference between one's complement and two's complement? One's complement negates a value by inverting every bit. Two's complement inverts every bit and then adds 1. One's complement ends up with two bit patterns for zero (positive and negative zero); two's complement has only one, which is a major reason two's complement became the standard.

Is the first bit in two's complement a sign bit? Not in the sense of an independent plus/minus flag. In an n-bit two's-complement interpretation, the most significant bit carries a real place value of -2^(n-1), while every other bit carries its usual positive power-of-two value. A pattern is negative when that weighted sum comes out negative, which happens whenever the MSB is 1.

Why is -128 representable in 8 bits but +128 is not? An 8-bit width has exactly 256 possible bit patterns. Two's complement uses one of them for zero, leaving 255 to split between positive and negative values — 127 positive values (1 to 127) and 128 negative values (-1 to -128). That asymmetry is why the negative range extends one value further than the positive range.

What does 11111111 represent in two's complement? In 8-bit two's complement, 11111111 represents -1. The same 8 bits represent a different value, 255, if interpreted as unsigned binary instead — the bit pattern alone doesn't carry its own signedness, the declared interpretation does.

Try Our Free SEO Tools

Put what you learned into action with our free SEO analysis tools.