🏆 US-Registered Digital Marketing Agency
Advertisement
Advertisement
DEVELOPER

Two's Complement Converter — signed integers at any bit width

Convert a signed integer to its two's complement bit pattern, or read a bit pattern back as a signed value, with overflow flagged.

Whole numbers only, positive or negative. Values outside the range for your bit width are wrapped and flagged rather than rejected.
Used in pattern mode. Spaces, underscores and a leading 0b or 0x are ignored.
Two's complement has no meaning without a width. The same pattern is a different number at every width.
Two's complement pattern
 
0
Hexadecimal
0
Same bits read as unsigned
0
One's complement pattern
0
Signed range at this width
Tip: the fastest hand method is not "invert and add one". Copy the bits from the right up to and including the first 1, then invert everything to the left of it. The two methods always agree.
Advertisement

The two's complement converter above works in both directions. Give it a signed decimal number and a bit width, and it produces the exact bit pattern a processor would store, in binary and hexadecimal, along with the one's complement pattern for comparison and the same bits read as an unsigned number. Give it a bit pattern instead and it tells you which signed value that pattern represents at the width you chose.

Arb Digital publishes it with the rest of its free developer utilities because two's complement is where a large share of real integer bugs live. Almost every mainstream language stores signed integers this way, almost every developer can recite "invert and add one", and almost nobody can say off the top of their head what 0xFF means without being told the width first. This page makes the width explicit and shows the wrap-around when a value does not fit.

What This Two's Complement Converter Does

In decimal mode it takes your number, reduces it modulo two to the power of the width, and prints the resulting pattern grouped in nibbles so you can read it. If the original value was outside the representable range for that width, it says so and shows the value you would actually get after wrapping — which is exactly what a fixed-width machine register does.

In pattern mode it reads binary or hexadecimal, pads or truncates to the chosen width, and reports both interpretations: the signed value under two's complement, and the plain unsigned value of the same bits. Seeing 214 and −42 next to each other for the pattern 11010110 is the clearest possible demonstration that a bit pattern has no inherent sign.

Arithmetic on very wide values uses arbitrary-precision integers, so 64-bit results are exact rather than rounded. That matters: a 64-bit signed minimum of −9,223,372,036,854,775,808 cannot be represented exactly in a double-precision float, so any tool that uses ordinary JavaScript numbers for this will quietly give you the wrong last few digits.

Boundary worth stating: our number base converter converts unsigned magnitudes between bases and knows nothing about sign bits or widths. This page is specifically about how a negative number is encoded in a fixed number of bits. For the arithmetic itself, the binary arithmetic calculator adds and subtracts in base two.

How to Use It

  1. Pick the direction — decimal in and bits out, or bits in and a decimal value out.
  2. Set the bit width first. Everything else depends on it, and getting it wrong is the usual cause of a surprising answer.
  3. Type your value or pattern. Underscores and spaces in a pattern are ignored, so you can paste grouped bits straight from a datasheet.
  4. Check the overflow line under the hero. If it reports wrapping, the number you typed does not fit and you are seeing the wrapped result.
  5. Press Negate to see the complement of what is currently displayed, which is the fastest way to check that a pair of values really are negatives of each other.

How Two's Complement Is Calculated

For a width of n bits, the two's complement encoding of a value v is v modulo 2 to the power n, taken as a non-negative remainder. Patterns whose top bit is 0 represent themselves; patterns whose top bit is 1 represent the pattern's unsigned value minus 2 to the power n. That single rule is the whole system, and the familiar "invert all the bits and add one" recipe is just a convenient way to compute it by hand.

Work −42 through at 8 bits. Write 42 in binary: 0010 1010. Invert every bit: 1101 0101, which is the one's complement pattern. Add one: 1101 0110. In hexadecimal that is D6, and read as unsigned it is 214. Check the rule: 214 minus 256 equals −42, which is what we started with. The tool shows all four of those numbers at once so the check is visible rather than implied.

The reason this encoding won is that it makes subtraction free. Because the representation is arithmetic modulo 2 to the power n, the same adder circuit that computes 5 + 3 computes 5 + (−3) with no special case for signs, no separate subtract unit, and no need to compare magnitudes first. Every mainstream language now mandates it: the Java Language Specification, chapter 4 on types and values defines byte, short, int and long as signed two's-complement integers, and the Rust Reference on numeric types does the same for i8 through i128.

Advertisement

The Asymmetric Range and the Value With No Negative

An n-bit two's complement field holds values from −2 to the power (n−1) up to 2 to the power (n−1) minus 1. At 8 bits that is −128 to 127. There is one more negative value than positive, and the reason is that zero occupies a slot in the non-negative half. All 2 to the power n patterns are used, with none wasted.

That asymmetry has a sharp consequence: the most negative value has no representable negative. Negating −128 at 8 bits should give 128, which does not fit, so the result wraps straight back to −128. A negation that returns its own input is deeply counter-intuitive and is a genuine source of production bugs — the absolute value of the minimum integer is itself, and still negative. Press Negate on −128 at 8 bits in the tool above and watch it happen.

This is why safe integer libraries treat negation and absolute value as fallible operations rather than total ones, and why a division of the minimum value by −1 traps on x86 rather than returning a value. It is not a hardware quirk; it is a direct consequence of using every available pattern.

Why One's Complement Lost

One's complement negates by inverting every bit and nothing else. It is simpler to describe, and the tool shows the pattern so you can compare, but it has two defects that two's complement does not. First, there are two zeros: all-zeros and all-ones both mean zero, which means an equality test against zero needs two comparisons and one pattern out of every 2 to the power n is wasted. Second, addition needs an end-around carry, where a carry out of the top bit must be added back into the bottom, which costs an extra pass through the adder.

Sign-magnitude, the third historical option, keeps a sign bit and an unsigned magnitude. It reads beautifully and adds terribly: the hardware must compare magnitudes and decide whether to add or subtract before it can do anything. It survives today in floating point, where the sign is a separate bit, which is exactly why floating point has both a positive and a negative zero. If you are chasing that behaviour, our floating point converter shows the IEEE 754 field layout directly.

Sign Extension, Truncation and Where Bugs Enter

Widening a signed value must copy the sign bit into every new high bit, not fill them with zeros. Widening 0xFF from 8 bits to 16 bits as a signed value gives 0xFFFF, still −1. Filling with zeros gives 0x00FF, which is 255. Both operations exist in every instruction set for good reason, and picking the wrong one is a classic defect — particularly in C, where whether a plain char is signed or unsigned is implementation-defined, so the same source file sign-extends on one platform and zero-extends on another.

Narrowing is the mirror image. Truncating discards the high bits, and the new top bit becomes the sign bit, so a positive 300 stored into 8 bits becomes 44 while a positive 200 becomes −56. Neither is an error the hardware will report. Set the width to 16, enter 200, then switch the width to 8 in the tool above and the change is immediate and visible.

The third trap is mixing signed and unsigned in a comparison. In C and C++ the usual arithmetic conversions promote the signed operand to unsigned, so comparing a negative signed value against an unsigned length turns the negative into a very large positive number and the comparison silently reverses. This has produced real buffer-overflow vulnerabilities. The grid above always shows both readings of the same bits so the two interpretations stay in front of you.

Reading Hex Dumps and Register Values

Most of the time you meet two's complement in the wild, it arrives as hexadecimal from a debugger, a memory dump or a device register. The quick test for negativity is the leading hex digit: 8 through F have the top bit set, so at the right width the value is negative. 0xFFFE at 16 bits is −2; 0x7FFF is 32,767, the largest positive value.

Sensor and audio data is where width mistakes bite hardest, because these formats are rarely a whole number of bytes. A 12-bit ADC reading arrives right-aligned in a 16-bit word, and interpreting the whole word as 16-bit signed gives nonsense for every negative reading unless you sign-extend from bit 11 first. Twenty-four-bit audio has the same shape. The width selector here includes 12 and 24 for exactly this reason. For network address fields, the IP address converter handles the unsigned dotted-quad case, and the bitwise calculator covers masking and shifting.

Need software that handles the edge cases?

Arb Digital builds web applications and integrations where overflow, encoding and boundary conditions are tested rather than assumed. Tell us what you are building.

See Web Design & Development Talk to Arb Digital

Common Mistakes to Avoid

  • Quoting a pattern without its width — 0xFF is −1 at 8 bits and 255 at 16. The pattern alone means nothing.
  • Zero-extending a signed value — widening must replicate the sign bit, or every negative number becomes a large positive one.
  • Assuming negation always works — the most negative value at any width negates to itself, and its absolute value is still negative.
  • Comparing signed against unsigned — in C-family languages the signed operand is converted to unsigned, which reverses the comparison for negative values.
  • Treating a 12- or 24-bit sample as its container width — sign-extend from the real top bit before interpreting the value.

Related Free Tools From Arb Digital

Convert unsigned magnitudes between bases with the number base converter, add and subtract in base two with the binary arithmetic calculator, mask and shift with the bitwise calculator, and inspect IEEE 754 fields with the floating point converter. For the logic behind the gates that make all of this work, try the truth table generator and the logic gate calculator. Everything else lives in the free online tools hub.

Frequently Asked Questions

What is two's complement in one sentence?

It is a way of storing signed integers in a fixed number of bits where a value is represented by its remainder modulo two to the power of the width, so patterns with the top bit set stand for negative numbers.

How do I convert a negative number by hand?

Write the magnitude in binary at the full width, invert every bit to get the one's complement, then add one. Alternatively copy bits from the right up to and including the first 1, then invert everything to the left of it.

Why is the negative range one larger than the positive range?

Because zero takes a slot in the non-negative half. With every pattern used and none wasted, an n-bit field runs from minus two to the power n minus one up to two to the power n minus one, minus one.

What happens when I negate the most negative value?

It returns itself. The positive counterpart does not fit in the width, so the result wraps back round. This also means the absolute value of the minimum integer is negative, which causes real bugs.

Is 0xFF equal to minus one?

Only at a width of 8 bits. At 16 bits the same digits are 255, a positive number. A hexadecimal pattern has no sign until you say how wide the field is.

What is the difference between one's and two's complement?

One's complement negates by inverting the bits alone, which produces two representations of zero and requires an end-around carry when adding. Two's complement adds one after inverting, giving a single zero and ordinary modular addition.

Why does my 12-bit sensor reading look wrong?

Because it arrives right-aligned inside a wider word. You must sign-extend from bit 11 before reading it as a signed value, or every negative reading is interpreted as a large positive one.

Does the tool handle 64-bit values exactly?

Yes. It uses arbitrary-precision integer arithmetic rather than floating-point numbers, so the 64-bit minimum and maximum are exact to the last digit.

Advertisement
Advertisement

Take it further