Skip to content

Two's Complement & Signed Integer Encoding Calculator

Type a signed integer and get sign-magnitude, ones' complement, two's complement and offset binary at once, at 4 to 64 bits. Or paste a bit pattern or hex byte and see all five readings side by side. Local, free, no sign-up.

No Tracking Runs in Browser Free
Everything is computed locally in your browser — nothing you type is uploaded.
Bit width

Decimal to machine representation

Type a signed whole number. All four representations are computed at once — you do not have to know in advance which one your system uses.

Try these
Encoding Bits Hex
Sign-magnitude 1000 0101 85
Ones' complement 1111 1010 FA
Two's complement 1111 1011 FB
Offset binary 0111 1011 7B

Bit pattern to value

You found a byte in a memory dump or a register and do not know how it is meant to be read. Paste it and see what it means under each interpretation at once — which one is right depends on the system that produced it, so all of them are shown.

Read as Value
Unsigned 251
Sign-magnitude -123
Ones' complement -4
Two's complement -5
Offset binary 123
8-bit reference table

Computed by the same engine the tool above uses, so these values cannot drift from it.

Decimal Sign-magnitude Ones' complement Two's complement Offset binary Hex
127 0111 1111 0111 1111 0111 1111 1111 1111 7F
100 0110 0100 0110 0100 0110 0100 1110 0100 64
10 0000 1010 0000 1010 0000 1010 1000 1010 0A
5 0000 0101 0000 0101 0000 0101 1000 0101 05
1 0000 0001 0000 0001 0000 0001 1000 0001 01
0 0000 0000 0000 0000 0000 0000 1000 0000 00
-1 1000 0001 1111 1110 1111 1111 0111 1111 FF
-5 1000 0101 1111 1010 1111 1011 0111 1011 FB
-10 1000 1010 1111 0101 1111 0110 0111 0110 F6
-100 1110 0100 1001 1011 1001 1100 0001 1100 9C
-127 1111 1111 1000 0000 1000 0001 0000 0001 81
-128 1000 0000 0000 0000 80
Value ranges by bit width
Width Two's complement / offset binary Sign-magnitude / ones' complement
4 -8 … 7 -7 … 7
8 -128 … 127 -127 … 127
16 -32768 … 32767 -32767 … 32767
32 -2147483648 … 2147483647 -2147483647 … 2147483647
64 -9223372036854775808 … 9223372036854775807 -9223372036854775807 … 9223372036854775807
Every encoding is asserted in the test suite across all five widths, including the full 4-bit range, both zero patterns, and the most negative value at each width. The 64-bit results are cross-checked against JavaScript's own BigInt.asIntN and BigInt.asUintN. — Go Tools Team · Sep 9, 2026

Built and verified by the Go Tools engineering team.

Quick answers

What is −5 in 8-bit two's complement?

11111011 11111011, which is 0xFB.

What is the range of a signed byte?

-128 … 127 −128 to 127 in two's complement; −127 to 127 in sign-magnitude and ones' complement.

How do I turn a two's complement pattern back into a number?

value − 2^n If the top bit is 0 read it as unsigned; if it is 1, subtract 2^n from the unsigned reading.

Does 0xFF mean −1 or 255?

−1 or 255 −1 as a signed byte, 255 as an unsigned one. The bits alone do not decide it.

What is two's complement?

Two's complement answers a hardware question, not a mathematical one: how do you store negative numbers so that the adder you already built keeps working? The trick is to represent −x by the pattern for 2^n − x. Addition then wraps around modulo 2^n and lands on the right answer with no special case for signs, which is why subtraction needs no separate circuit.

Two consequences follow and both show up in real bugs. First, the range is asymmetric: eight bits cover −128 to 127, not −128 to 128, because the patterns have to be shared out and there is no negative zero to make things even. Second, the sign is not a flag you can strip — the top bit of 11111011 is 1, but the value is −5 rather than −123, so reading a negative number means interpreting the whole word, not just looking at one bit.

Sign-magnitude and ones' complement are the two designs that lost. They are still worth knowing because IEEE 754 floating point kept the sign-magnitude layout, and because the comparison is what makes two's complement look inevitable rather than arbitrary.

// -5 as an 8-bit byte, three ways to arrive at the same pattern
0b00000101        // 5
~0b00000101       // 11111010  ones' complement of 5
~0b00000101 + 1   // 11111011  two's complement = -5

// In JavaScript the width matters: bitwise operators are 32-bit,
// so anything wider has to go through BigInt.
BigInt.asIntN(8, 0xFBn)                 // -5n
BigInt.asUintN(8, -5n)                  // 251n
BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn)  // -5n

// C23 made two's complement mandatory for signed integers.
// Before that, the other two encodings were legal but unused.

What this calculator does

Four encodings at once

Sign-magnitude, ones' complement, two's complement and offset binary are computed together. Offset binary is the one most calculators leave out, and it is the one ADC datasheets keep using.

Reverse lookup from a bit pattern

Paste the bits or the hex you actually have and see all five readings, unsigned included. This is the direction you need when a dump disagrees with the number the device reports.

Correct at 64 bits

Every value is handled with BigInt, so 0xFFFFFFFFFFFFFF9C resolves to −100 rather than to whatever a 32-bit truncation would produce.

Honest about what has no representation

At width 8, −128 has no sign-magnitude and no ones' complement form. The table says so instead of printing a pattern that does not mean that number.

Negative zero made visible

Enter 0 and the second bit pattern for zero in sign-magnitude and ones' complement is shown, which is the clearest single argument for why two's complement won.

Reference tables without JavaScript

The 8-bit comparison table and the per-width ranges are rendered when the page is built, by the same engine that powers the live fields, so they cannot drift out of sync with it.

How this compares to other ways of checking

Your language's own conversion

Runtime API

BigInt.asIntN, Python's int.from_bytes(..., signed=True) and C's fixed-width types give the authoritative answer for the code you are writing. Use them in the code; use this page when you have a value in front of you and no interpreter open.

A debugger memory view

IDE feature

Shows the value with the type the program declared, which is exactly the piece of information a bit pattern lacks. It cannot help when the bytes arrived over a wire with no declared type — that is the case this page is for.

Base converter

This site

Converts between bases, but only for non-negative values — negatives are explicitly rejected there because a base has no opinion about how a sign is stored. Signed representation is this page's job; use the base converter for magnitudes.

IEEE 754 converter

This site

The floating-point counterpart. It keeps a sign-magnitude layout rather than two's complement, and biases the exponent by 2^(e−1)−1, so the two pages answer different questions about the same word of memory.

Worked examples

−5 as an 8-bit byte

-5, width 8
sign-magnitude  1000 0101
ones' complement 1111 1010
two's complement 1111 1011  (0xFB)
offset binary    0111 1011

The three encodings agree on the sign bit and disagree on everything else. Only the two's complement row is what a C int8_t actually holds.

The byte 0xFB, read five ways

0xFB, width 8
unsigned         251
sign-magnitude   -123
ones' complement -4
two's complement -5
offset binary    123

−128 has no sign-magnitude form

-128, width 8
sign-magnitude   no representation
ones' complement no representation
two's complement 1000 0000  (0x80)
offset binary    0000 0000

Sign-magnitude and ones' complement each spend a bit pattern on negative zero, so they run from −127 to 127 and cannot reach −128. Tools that print a byte here are wrong.

A 64-bit register value

0xFFFFFFFFFFFFFF9C, width 64
two's complement -100
unsigned         18446744073709551516

Anything wider than 32 bits has to be done with BigInt. JavaScript's |, << and >>> truncate to 32 bits silently, which is why some online calculators return the wrong answer here instead of an error.

How to use the complement calculator

  1. 1

    Choose the bit width

    4, 8, 16, 32 or 64. This is not a display preference — the same bits mean different numbers at different widths, so getting it wrong changes the answer.

  2. 2

    Enter a signed decimal

    Type a whole number, negative sign included. All four encodings update as you type, together with the hexadecimal form of each.

  3. 3

    Or go backwards from bits

    Paste a binary string or a 0x value into the reverse field to see what that exact pattern means under each interpretation, including the unsigned reading.

  4. 4

    Read the notes when they appear

    The page flags the two cases that trip people up: the most negative value having no sign-magnitude or ones' complement form, and zero having a second bit pattern in those two encodings.

Mistakes that produce wrong answers

Forgetting the +1

Inverting the bits gives the ones' complement. Stopping there is off by one from the two's complement, and the error is easy to miss because the result still looks like a plausible negative number.

✗ Wrong
5   = 00000101
~5  = 11111010   <- ones' complement, not -5
✓ Correct
5        = 00000101
~5       = 11111010
~5 + 1   = 11111011   <- -5 in two's complement

Using 32-bit bitwise operators on a 64-bit value

JavaScript truncates the operands of bitwise operators to 32 bits. The high half disappears with no error, so the result is wrong rather than absent.

✗ Wrong
0xFFFFFFFFFFFFFFFB        // 18446744073709552000  -- the literal is already rounded
~0xFFFFFFFFFFFFFFFB + 1   // 0  -- silently wrong, expected -5
✓ Correct
BigInt.asIntN(64, 0xFFFFFFFFFFFFFFFBn)   // -5n

Zero-extending a negative value

Widening by padding with zeros keeps the number only when it is positive. For a negative value the sign bit has to be replicated across the new bits.

✗ Wrong
int8  0xFB  (-5)
int16 0x00FB  (251)   <- zero-extended
✓ Correct
int8  0xFB  (-5)
int16 0xFFFB  (-5)    <- sign-extended

Giving the most negative value a sign-magnitude form

−128 has no sign-magnitude and no ones' complement representation in eight bits, because both encodings spend one pattern on negative zero. Printing 10000000 for it confuses the two's complement answer with an encoding that cannot express the number.

✗ Wrong
-128 sign-magnitude: 10000000   <- that pattern means -0
✓ Correct
-128 sign-magnitude: no representation at width 8
-128 two's complement: 10000000

When you actually need this

Reading a sensor register
A temperature register returns 0xFF9C. Unsigned that is 65436, which is not a temperature. At width 16 the two's complement row shows −100, and with a 0.1 °C scale factor the sensor is telling you −10.0 °C.
Debugging a protocol with untyped fields
Modbus, CAN and most binary telemetry carry raw words with no signedness attached. When a client and a device disagree about a value, checking both readings of the same word usually identifies which side made the wrong assumption.
Coursework on computer organisation
Sign-magnitude, ones' complement, two's complement and offset binary are the standard four in an introductory course. Having them side by side at the same width makes the differences visible rather than memorised.
Chasing integer overflow
When a counter jumps from 2147483647 to −2147483648, seeing both as 32-bit patterns shows the carry landed in the sign bit. The value did not become nonsense; it wrapped exactly as the encoding says it should.
Writing serialisation code
Before trusting a hand-written encoder, check one negative value at each width against this page. A sign error is easy to write and produces output that looks structurally fine right up until a real negative number arrives.

How the four encodings are built

Sign-magnitude
The top bit is the sign and the remaining n−1 bits are the magnitude, read as a plain unsigned number. Range is −(2^(n−1)−1) to 2^(n−1)−1, symmetric, with two zeros. It is the layout IEEE 754 uses for floating point.
Ones' complement
A negative value is the bitwise inverse of its magnitude, equivalently 2^n − 1 − x. Same range and same two zeros as sign-magnitude. Addition needs an end-around carry, which is exactly the complication two's complement removes. The apostrophe placement is not a typo: ones' complement is relative to a word of all ones, while two's complement is relative to a single power of two.
Two's complement
A negative value −x is stored as 2^n − x. Range is −2^(n−1) to 2^(n−1)−1, deliberately asymmetric, with one zero. Addition, subtraction and multiplication of the low word are all sign-agnostic, which is the whole reason it won.
Offset binary
Stores value + 2^(n−1), so −2^(n−1) becomes all zeros and the patterns sort in the same order as the values they encode. It equals the two's complement pattern with the top bit flipped. Beware the naming: IEEE 754 exponent fields are biased by 2^(e−1)−1, one less than the offset used here.
Why the arithmetic uses BigInt
JavaScript converts operands of &, |, ~ and the shifts to 32-bit integers before operating and converts back afterwards, so a 64-bit value loses its high half without any error being raised. Every conversion on this page is done on arbitrary-precision integers instead, which is also why the 64-bit extremes come out exact.

Getting signed values right

Fix the width before anything else
A bit pattern has no value until you say how wide the field is. Most disagreements between a datasheet and a debugger come down to one side assuming 16 bits and the other 32.
Treat the most negative value as a special case
Negating it overflows in every width — in two's complement −(−128) is still −128 for a signed byte. Any code that computes an absolute value needs a plan for this input, and any test suite should contain it.
Never infer signedness from the data
No inspection of the bits can tell you whether a field is signed. Get it from the datasheet, the schema or the struct definition; guessing works until the first negative value arrives in production.
Sign-extend when you widen
Copying an 8-bit 0xFB into a 16-bit field as 0x00FB turns −5 into 251. Widening a signed value means replicating the sign bit, giving 0xFFFB.
Prefer the language's own conversion
BigInt.asIntN in JavaScript, int.from_bytes(..., signed=True) in Python and fixed-width types in C say what they mean and handle the edges. Hand-rolled ~x + 1 is where the width bugs come from.

Frequently asked questions

What is two's complement, in one sentence?
It is the convention where a negative number −x is stored as the bit pattern for 2^n − x, which makes subtraction and addition the same circuit and gives the number line exactly one zero.
How do I work out a two's complement by hand?
Write the magnitude in binary, flip every bit, then add 1. For 5 in eight bits: 000001011111101011111011. The flip step alone gives you the ones' complement, which is why the two are always one apart.
Why does −128 fit in a signed byte but +128 does not?
Two's complement is deliberately lopsided. With n bits it covers −2^(n−1) to 2^(n−1)−1, because it does not waste a pattern on negative zero the way sign-magnitude and ones' complement do. That extra slot lands on the negative side.
Is 11111011 equal to −5 or to 251?
Both, and the bits cannot tell you which. The answer depends on the type the producing system declared. That is why the reverse lookup on this page shows every reading at once instead of picking one for you — pick the row that matches your int8_t or uint8_t.
What is offset binary and where would I meet it?
Offset binary (also called excess-K or biased) stores value + 2^(n−1), so the smallest value is all zeros and ordering the raw patterns as unsigned integers also orders the signed values. It shows up in ADC and DAC outputs and in audio sample formats. Note that IEEE 754 exponents use a different bias — 2^(e−1)−1, not 2^(e−1) — so do not carry the number across.
Why does a Modbus register read 65436 when the sensor says −100?
Modbus transports 16-bit words with no type information, so a client that assumes unsigned prints 65436 while the device meant the two's complement value −100. Paste 65436 as hex 0xFF9C at width 16 here and the two's complement row shows the intended reading.
Do sign-magnitude and ones' complement still get used?
Rarely for integers — essentially every current CPU uses two's complement, and C23 finally made it mandatory. They stay relevant because IEEE 754 floating point keeps a sign-magnitude layout, and because both still appear in exam questions on computer organisation.
Why do some calculators give a wrong answer for 64-bit values?
JavaScript's bitwise operators convert their operands to 32-bit integers first, so a page that uses ~x + 1 silently loses the top half of a 64-bit value and reports a plausible but wrong result. This tool uses BigInt throughout, which is why the 64-bit rows here agree with what your debugger shows.
What is negative zero and why does it matter?
In sign-magnitude, 00000000 and 10000000 both mean zero; in ones' complement it is 00000000 and 11111111. Two comparisons that should be equal can therefore compare unequal bit by bit. Two's complement has a single zero, which removed a whole class of hardware special cases.
Is anything I type sent to a server?
No. The page ships the conversion engine to your browser and runs it there. Register dumps and firmware values often come from systems you are not free to share, so there is nothing to trust here beyond the network tab — no request is made.

Related Tools

View all tools →