
Signed Binary and Two's Complement (Negative Numbers)
Two's complement represents signed integers in a fixed number of bits. It is commonly used for negative offsets, temperatures, and other integer values. This guide encodes -5 in eight bits, checks the signed range, and shows how sign extension preserves a value.
Why signed binary needs a convention
With 8 bits you can store 256 distinct patterns. If every pattern means a positive count, you get 0 through 255. If you want negatives, you have to reserve some patterns for them. That choice is the signed representation.
Early machines tried sign-magnitude and ones' complement. Both made arithmetic awkward (two zeros, messy addition). Two's complement won because addition and subtraction use the same hardware circuits for signed and unsigned values.
The invert-and-add-one recipe
To encode -N in a fixed width:
- Write the positive value
Nin binary, padded to the bit width. - Invert every bit (0 becomes 1, 1 becomes 0).
- Add 1, ignoring any carry past the width.
Decoding works the same way: invert and add one to recover the magnitude when the high bit is set. Or treat the pattern as an unsigned integer and subtract 2width when the sign bit is 1.
Worked example: encode −5 in 8 bits
From +5 to −5
Step 1: +5 = 00000101
Step 2: invert → 11111010
Step 3: add 1 → 11111011
So −5 as an 8-bit two's complement value is 11111011.
Check: unsigned reading of 11111011 is 251. Then 251 − 256 = −5. Same answer, different mental path.
Range of an 8-bit signed integer
The top bit is the sign bit. Patterns starting with 0 are non-negative. Patterns starting with 1 are negative. That gives:
- Minimum:
10000000= −128 - Maximum:
01111111= +127 - Zero:
00000000(only one zero)
Notice −128 has no positive counterpart inside 8 bits. You cannot form +128, so negating −128 overflows. That quirk shows up in real bugs when someone writes -INT_MIN on a fixed-width type.
Quick reference table (−8 through +7)
A short slice of the 8-bit two's complement map. Useful when you are reading dumps or debugging casts.
| Decimal | Binary (8-bit) | Hex |
|---|---|---|
| +7 | 00000111 | 07 |
| +5 | 00000101 | 05 |
| +1 | 00000001 | 01 |
| 0 | 00000000 | 00 |
| −1 | 11111111 | FF |
| −5 | 11111011 | FB |
| −8 | 11111000 | F8 |
| −128 | 10000000 | 80 |
| +127 | 01111111 | 7F |
Addition still works the obvious way
Add −5 and +3 using ordinary binary addition, keep 8 bits:
11111011 (−5)
+ 00000011 (+3)
11111110 (−2)
No special "signed add" instruction required at the bit level. Overflow detection is separate: if two positives sum to a negative pattern (or two negatives to a positive), the result left the representable range.
Sign extension when you widen
Cast an 8-bit −5 to 16 bits and you must copy the sign bit into the new high bits:
11111011 → 11111111 11111011
Zero-extension would turn −5 into 251. That is a common bug when mixing uint8_t and wider signed types. Hex dumps make the difference obvious; try the hex viewer when you are staring at raw bytes.
Comparing with IEEE floating formats
Integers use two's complement. IEEE 754 floats use a separate sign bit plus biased exponent and fraction. You cannot read a float's bits as a two's complement int and expect a sensible value.
If you need to inspect float layouts, use the IEEE 754 converter. For plain integer binary, stick with the binary converter.
Where you meet this in practice
- Language types:
int8_t, Javabyte, Goint8 - Protocols that send signed deltas or relative offsets
- Image formats with signed sample differences
- Bitwise flags that also carry a signed payload in the same word (rare, but messy)
For bitmasks and permission flags (unsigned patterns), see binary ops in programming. Two's complement is about numeric meaning of the same bit patterns.
Common mistakes
- Forgetting to pad before invert. Inverting
101is not the same as inverting00000101. - Stopping after invert (that is ones' complement, not two's).
- Reading a signed byte as unsigned in a debugger and wondering why −1 became 255.
- Assuming the high bit alone means "negative" without checking the width you agreed on.
FAQ
Is −1 always all ones?
Yes, in two's complement of any width. 8-bit −1 is 11111111. 16-bit −1 is sixteen ones. That is why people joke that −1 is the "all bits set" value.
How do I convert −5 by hand quickly?
Write +5, invert, add 1. Or memorize that −1 is all ones and count backward: −2 is all ones minus one bit, and so on. For odd values like −5, the invert-and-add path is usually clearer.
Does ASCII use two's complement?
No. Character codes are unsigned byte values. See the ASCII table. Two's complement shows up when those bytes are interpreted as signed integers in code.
What about 32-bit and 64-bit?
Same rules, larger ranges. 32-bit signed ints run from −231 to 231−1. The encoding steps do not change.
Try it in the converter
Practice with positive values first, then check how your language prints the same bits as signed. The main BinaryTranslator suite and the binary converter help you move between binary, decimal, and hex while you verify hand work.
Encode -5 in eight bits, then decode the result by subtracting 256 from its unsigned value. Repeat with -8 and -1 to check that you can use both methods.
Check the examples
Technical reference
Related Articles

Binary to Decimal Converter: Powers of 2 Method
Convert any binary string to decimal by adding place values. Worked examples, a practice set, and a free online converter.
Binary Operations in Programming: A Practical Guide
Use bitwise operators in JavaScript examples. Bitwise operators, masks, flags, and performance optimization techniques.

IEEE 754 Explained: Float to Binary (Sign, Exponent, Mantissa)
Break a floating-point number into sign, exponent, and mantissa bits. Single vs double precision with a worked example you can verify in the calculator.
