Number Systems & Conversions
How digital systems represent quantities in binary, octal, and hexadecimal — and why each one matters.
A computer only knows two things — on and off, 1 and 0 — yet it processes numbers, text, images, and everything in between. How does that work?
Positional notation: the one idea behind every base
You already use positional notation every day. In the decimal number 173, the digit 1 contributes one hundred (1 × 10²), the digit 7 contributes seventy (7 × 10¹), and the digit 3 contributes three (3 × 10⁰). The base — or radix — is 10, and each position carries a weight that is a power of that base.
This same principle generalizes to any base r. A number with digits d_(n-1) ... d_1 d_0 in base r has the value:
The only thing that changes from one system to another is the radix and the set of allowed digits. Binary uses base 2 with digits {0, 1}. Octal uses base 8 with digits {0–7}. Decimal uses base 10 with digits {0–9}. Hexadecimal uses base 16 with digits {0–9, A–F}, where A = 10, B = 11, C = 12, D = 13, E = 14, F = 15.
Binary to decimal: sum the powers of 2
Because binary is base 2, each bit position carries a weight of 2 raised to that position index. To convert binary to decimal, add up the weights of every position that holds a 1.
The position weights from right to left are: 1, 2, 4, 8, 16, 32, 64, 128, 256, ... (doubling each time). Memorizing the first eight or ten powers of 2 makes this conversion fast and intuitive.
- Write out each bit position and its weight (powers of 2): bit 7 = 128, bit 6 = 64, bit 5 = 32, bit 4 = 16, bit 3 = 8, bit 2 = 4, bit 1 = 2, bit 0 = 1.
- Sum only the weights where the bit is 1: positions 7, 5, 3, 2, and 0 are set.
- Compute: 1×128 + 0×64 + 1×32 + 0×16 + 1×8 + 1×4 + 0×2 + 1×1 = 128 + 32 + 8 + 4 + 1.
- Add them up: 128 + 32 = 160, plus 8 = 168, plus 4 = 172, plus 1 = 173.
Decimal to binary: repeated division by 2
Going the other direction — decimal to binary — the standard method is repeated division by 2. Divide the number by 2, record the remainder (0 or 1), then divide the quotient by 2 again. Repeat until the quotient reaches 0. The binary result is the sequence of remainders read bottom to top (last remainder first).
An alternative is the subtract-the-largest-power method: find the largest power of 2 that fits into the number, subtract it, place a 1 in that bit position, and repeat with the remainder. Both methods produce identical results.
- 173 ÷ 2 = 86 remainder 1 (this is the LSB, bit 0).
- 86 ÷ 2 = 43 remainder 0 (bit 1).
- 43 ÷ 2 = 21 remainder 1 (bit 2).
- 21 ÷ 2 = 10 remainder 1 (bit 3).
- 10 ÷ 2 = 5 remainder 0 (bit 4).
- 5 ÷ 2 = 2 remainder 1 (bit 5).
- 2 ÷ 2 = 1 remainder 0 (bit 6).
- 1 ÷ 2 = 0 remainder 1 (bit 7, the MSB).
- Read remainders bottom to top: 10101101.
- Verify: 128 + 32 + 8 + 4 + 1 = 173 ✓.
- Identify which bit positions are 1: bits 7, 6, 4, 3, and 1.
- Sum the corresponding powers of 2: 128 + 64 + 16 + 8 + 2.
- 128 + 64 = 192, plus 16 = 208, plus 8 = 216, plus 2 = 218.
Hexadecimal: groups of 4 bits
Hexadecimal (base 16) is the most compact common representation for binary data, and it maps cleanly because 16 = 2⁴. Every group of 4 binary bits corresponds to exactly one hexadecimal digit. To convert binary to hex, split the binary string into 4-bit groups from right to left (padding with leading zeros if needed), then replace each group with its hex equivalent.
The 16 hex digits and their binary equivalents: 0 = 0000, 1 = 0001, 2 = 0010, 3 = 0011, 4 = 0100, 5 = 0101, 6 = 0110, 7 = 0111, 8 = 1000, 9 = 1001, A = 1010, B = 1011, C = 1100, D = 1101, E = 1110, F = 1111.
- Split into 4-bit groups from the right: 1010 1101.
- Convert each group: 1010 = A (10), 1101 = D (13).
- Combine: the hex representation is AD, conventionally written as 0xAD.
- Verify: A×16 + D = 10×16 + 13 = 160 + 13 = 173 ✓.
Octal: groups of 3 bits
Octal (base 8) works the same way, but since 8 = 2³, each group of 3 binary bits maps to one octal digit. Split the binary string into 3-bit groups from right to left, padding the leftmost group with leading zeros to fill 3 bits if necessary.
- Pad to a multiple of 3 bits: 010 101 101 (added one leading zero).
- Convert each 3-bit group: 010 = 2, 101 = 5, 101 = 5.
- Combine: the octal representation is 255, written as 0o255.
- Verify: 2×64 + 5×8 + 5×1 = 128 + 40 + 5 = 173 ✓.
Binary Coded Decimal (BCD): a different encoding
Binary Coded Decimal (BCD) is not the same as converting the full number to binary. In BCD, each individual decimal digit is encoded separately as a 4-bit binary value. This means a number like 173 — which is a single 8-bit value (10101101) in pure binary — becomes three separate 4-bit groups in BCD: one for each decimal digit.
BCD is useful in applications like digital displays and financial calculations where you need each decimal digit to be independently accessible and exact decimal arithmetic matters. The trade-off is efficiency: 4 bits can represent 16 values (0–15), but BCD only uses 10 of them (0–9), so the patterns 1010 through 1111 (A–F in hex) are unused and invalid in BCD.
- Separate the decimal digits: 1, 7, 3.
- Encode each as 4-bit binary: 1 → 0001, 7 → 0111, 3 → 0011.
- Concatenate: 0001 0111 0011 — this is the BCD representation, using 12 bits total.
- Contrast: the pure binary equivalent of 173 is 10101101 (8 bits) — a completely different bit pattern.
- Key point: BCD encodes each decimal digit independently, while binary encodes the entire numeric value as one number.
- 3C = 3 × 16 + 12 = 48 + 12 = 60.
- Recall that C in hexadecimal equals decimal 12.
Check your understanding
- Any positional number's value is the weighted sum of its digits times powers of the radix: value = Σ(di × ri).
- Binary-to-decimal conversion sums the powers of 2 at each bit position that holds a 1; decimal-to-binary uses repeated division by 2, reading remainders bottom to top.
- Hexadecimal (base 16 = 2⁴) converts from binary by grouping 4 bits per hex digit; octal (base 8 = 2³) groups 3 bits per octal digit.
- BCD encodes each decimal digit independently in 4 bits — it is a different encoding than pure binary and uses more bits for the same value.