Live conversion between binary, decimal, hexadecimal, octal, and binary-coded decimal (BCD). Signed and unsigned modes with 8/16/32/64-bit widths. Type in any field — the others update instantly.
A number system is just a way of writing a value. The value 255 and the value 0xFF and the value 11111111 are all the same underlying quantity — one byte at maximum. The only thing that changes is the base you're counting in.
Binary (base 2): each digit represents a power of 2. This is what silicon actually stores. Every register, every memory cell, every wire carries binary — a voltage that's either high (1) or low (0).
Hexadecimal (base 16): the compact form of binary. Each hex digit maps to exactly 4 binary bits (a nibble), so 0xAC unpacks as 1010 1100 — no math required. This is why memory addresses, RGB colors, and machine code all get written in hex: it's binary with 1/4 the visual noise.
Octal (base 8): each digit maps to 3 bits. Common in Unix file permissions (chmod 755) and some older systems, but mostly a curiosity today. Predates hex in the history of computing.
BCD (binary-coded decimal): each decimal digit gets its own 4-bit binary block. Decimal 25 becomes 0010 0101, not 00011001. Wasteful for storage but avoids decimal-to-binary rounding — the reason it survives in real-time clock chips (DS1307, DS3231), 7-segment display drivers, and financial systems that can't tolerate rounding errors on money.
To represent negative numbers, most modern systems use two's complement. The leftmost bit (MSB) becomes a sign flag: 0 for positive, 1 for negative. To negate a number, flip every bit and add 1.
Example at 8-bit: decimal 5 is 00000101. Decimal −5 is 11111011. Flip all bits of 5 to get 11111010, add 1, get 11111011. ✓
Two's complement is elegant because the CPU can add signed numbers using the exact same circuitry as unsigned addition. The bit patterns just wrap around modulo 2ⁿ, and the interpretation happens at a higher layer.
Range for signed: −2ⁿ⁻¹ to 2ⁿ⁻¹−1. For 8-bit that's −128 to 127. For 16-bit, −32,768 to 32,767. For 32-bit, ±2.1 billion. The signed range is one less on the positive side because zero takes a slot on the positive side.
11111111 is 255 if you treat it as unsigned, and −1 if you treat it as signed. Neither is "correct" — they're both valid interpretations of the same silicon. That's why C has uint8_t and int8_t as separate types — the compiler needs to know which lens to use.