Two's Complement Converter
Convert between decimal integers and two's complement binary — 8, 16, 32, or 64-bit.
How two's complement works
Two's complement is the standard way computers represent signed integers. For a positive number, it's the same as unsigned binary. For a negative number: invert all bits and add 1. The most significant bit (MSB) is the sign bit — 0 = positive, 1 = negative.
To work with binary numbers generally, see Binary to Decimal and Decimal to Binary. For bitwise operations, try Bitwise Calculator.
Built and maintained by Meet Shah · Last updated
What this tool is used for
- Reading a negative value out of a register dump or a protocol field.
- Checking what a signed 8-bit value wraps to at the boundary.
- Confirming your own sign-extension logic against a known width.
- Understanding why an integer overflowed to a negative number in a bug report.
- Converting a decimal offset into the bit pattern a low-level format expects.
How it works in practice
A worked example
A firmware developer reads a 16-bit accelerometer register over I2C, gets back FF38, and needs to know whether the axis is reporting a large positive value or a small negative one.
Conversion mode Binary → Decimal Bit width 16-bit Binary (two's complement) 1111 1111 0011 1000
Decimal -200 Hexadecimal 0xFF38 Bit width 16-bit
The leading 1 is the sign, but it is not a flag bolted onto an ordinary number: at 16 bits the top position is worth −32,768 instead of +32,768, and the other fifteen bits keep their usual positive weights, which here add up to 32,568, so the register holds −200. The hex card is the same sixteen bits written four to a digit, which is why FF38 comes straight back. Decode the register as unsigned instead and the same bits read 65,336, the usual symptom of a signed register handled as if it had no sign.
The edge case that catches people
Bits you do not type are zeros, never copies of the sign. Switch the same sixteen digits to 32-bit and the answer becomes 65336, hex 0x0000FF38, because the pattern is placed at the low end of a 32-bit field and the new top bit is 0; type 1010 at 8 bits and you get 10, not the −6 it means in a 4-bit field. The width selector is part of the value, and a short pattern is always read as if it had been zero-extended, so a narrower signed field has to be sign-extended by hand, by copying its top bit leftwards, before it is typed in.
When not to use this tool
Only four widths are on offer, 8, 16, 32 and 64 bits, and real hardware is full of fields in between, such as a 12-bit temperature reading or a 24-bit audio sample. Those have to be sign-extended to the next width by hand first, as above. Input is decimal or binary only, so a hex register dump has to be expanded to binary before it goes in, and nothing here understands fixed-point formats such as Q15 or floating point; a register that holds a scaled or IEEE 754 value needs its own decoder once the bits are known.
Frequently Asked Questions
- Why is two's complement used instead of a sign bit?
- Because addition then works unchanged for negative numbers — no special case, no separate subtract circuit. It also gives exactly one zero, where a sign-and-magnitude representation has both +0 and −0 and has to decide whether they are equal.
- How do I negate a number by hand?
- Invert every bit and add one. 5 in 8-bit is 00000101; inverted it is 11111010; plus one is 11111011, which is −5. Doing it twice returns you to where you started, which is the property that makes the representation work.
- Why is the negative range one larger?
- 8-bit signed runs from −128 to +127, not −127. Zero takes one of the positive slots, so there is one more pattern available below zero. That asymmetry is real: negating −128 in 8 bits overflows back to −128, and the same trap exists at every width.
- Is the arithmetic exact at 64 bits?
- Yes — everything here runs on BigInt. A double cannot do this: it is exact only to 2⁵³, so a 64-bit conversion done in ordinary JavaScript numbers prints int64 maximum as 9223372036854776000 and turns −1 into a 65-bit string.
- How does sign extension work?
- Widening a negative number copies the sign bit leftwards: −5 as 11111011 in 8 bits becomes 1111111111111011 in 16. Copying zeros instead — a zero extension — would turn −5 into 251, which is the classic bug when a signed byte is read as unsigned.
Common errors and gotchas
- Converting without choosing a width first, which makes the answer undefined for any negative value.
- Sign-extending when you meant to zero-extend, which turns a small positive into a large negative.
- Confusing the sign bit with a flag bit in a field that packs both.
- Assuming the range is symmetric, when the negative side reaches one further than the positive.
- Reading a hex value as unsigned by default, so
FFis 255 in one reading and -1 in another.