bitlvl
EN

Two's complement converter

Enter a decimal number (negative is fine), or a binary or hex bit pattern, and see how it is stored and read at the width you choose.

Width
Sign bit

How two's complement works

Computers have no minus sign, only bits. Two's complement is the convention almost every CPU uses to store negative integers: the top bit (the sign bit) counts as negative 2ⁿ⁻¹ instead of positive. In 8 bits, the top bit is worth −128, so 1111 1111 = −128 + 64 + 32 + 16 + 8 + 4 + 2 + 1 = −1, and 1000 0000 is −128.

The same bits read as unsigned are 255 and 128. Whether a value is “really” negative is decided by the type in your code (int8_t versus uint8_t), not by the bits. That is why this tool always shows both readings.

Negating a number by hand

  1. Write the positive value in binary at the full width (42 = 0010 1010).
  2. Invert every bit (1101 0101).
  3. Add 1 (1101 0110). That is −42, which is 0xD6 or 214 unsigned.

The trick works in both directions: applying it to −42 gives 42 back. The tool above prints these steps for whatever you enter.

Why it is designed this way

With two's complement the hardware does not need a separate subtractor. Adding a negative number is ordinary binary addition with the carry out of the top bit thrown away: 42 + (−42) = 0010 1010 + 1101 0110 = 1 0000 0000, drop the ninth bit, get 0. There is also only one zero, unlike sign-magnitude or one's complement.

Ranges

WidthSigned rangeUnsigned rangeTypical type
8−128 … 1270 … 255int8_t, byte
16−32,768 … 32,7670 … 65,535int16_t, short
32−2,147,483,648 … 2,147,483,6470 … 4,294,967,295int32_t, int
64−9.22 × 10¹⁸ … 9.22 × 10¹⁸0 … 1.84 × 10¹⁹int64_t, long

The negative range is one larger than the positive, because zero takes one of the “positive” patterns. That is why -INT_MIN overflows: 128 does not fit in a signed byte.

Questions

What is −1 in two's complement?

All ones: 0xFF in 8 bits, 0xFFFF in 16, 0xFFFFFFFF in 32. Inverting 0000 0001 gives 1111 1110, adding 1 gives 1111 1111.

How do I tell if a binary number is negative?

Look at the leftmost bit at the declared width. If it is 1 and the value is signed, the number is negative. 1000 0000 is −128 as int8 but 128 as uint8; the bits alone do not decide.

Why does 127 + 1 give −128?

Signed overflow. 0111 1111 + 1 = 1000 0000, which sets the sign bit. In C this is undefined behaviour; in most other languages the value wraps around to −128.

What is sign extension?

Widening a signed value by copying the sign bit into the new top bits, so −1 (0xFF) becomes 0xFFFF, not 0x00FF. Casting an int8 to int16 does this automatically; casting an unsigned does zero extension instead. Switch widths above with a negative number entered to see it.

Is the sign bit just a flag?

No. In two's complement the sign bit has a value (−2ⁿ⁻¹) and takes part in the arithmetic. That differs from sign-magnitude, where the top bit only marks the sign, and from floating point, where the sign is a separate flag.