HandyTools Hub

← All guides

Binary, Octal, Decimal, Hex: A Developer's Guide to Number Base Conversion

2026-08-12

0xFF, 0b1010, 0755, 255 — four ways to write numbers that show up constantly in code, config files, permissions, colors, and network addresses. Every programmer develops a rough fluency with binary and hex over time, but it’s often pattern-matching rather than understanding: you know 0xFF is 255 because you’ve seen it a thousand times, not because the conversion is obvious. This guide builds the actual understanding — what a “base” is, how to convert between any two of them, and the mental shortcuts that make hex and binary feel as natural as decimal.

What a “Base” Actually Is

All the number systems above are the same idea with a different width: positional notation. The number 255 in decimal means 2×100 + 5×10 + 5×1 — each digit’s value is its face value times a power of 10, and the power is determined by position. Change the multiplier from powers of 10 to powers of some other number b, and you get base b. You need exactly b distinct digit symbols:

  • Binary (base 2): digits 0–1. Powers of 2.
  • Octal (base 8): digits 0–7. Powers of 8.
  • Decimal (base 10): digits 0–9. Powers of 10.
  • Hexadecimal (base 16): digits 0–9 plus A–F for values 10–15. Powers of 16.

So 1010 in binary means 1×8 + 0×4 + 1×2 + 0×1 = 10, and FF in hex means 15×16 + 15×1 = 255. That single expansion — digit times base-to-the-position, summed — is every conversion formula in disguise. Any base → decimal is literally just writing out this sum.

Why Programmers Live in Binary and Hex

Computers store everything as bits, so binary is the ground truth — but raw binary is unreadable at any length: 11111111 strains the eye, and 32-bit values are hopeless. Hex solves this because of one beautiful coincidence: 16 is 2⁴, so exactly one hex digit maps to exactly four binary digits (a nibble). Converting hex ↔ binary requires no arithmetic at all, just a 16-row lookup table:

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

0xF5F=1111, 5=0101 → 11110101. Going the other way, group binary into fours from the right and translate each group. This is why hex appears anywhere humans must read raw bytes: memory addresses, MAC addresses, color codes (#FF5733 is three bytes), file signatures, hashes. One byte = two hex digits, always.

Octal survives for the same reason with groups of three (8 = 2³): one octal digit = three bits. Its main modern habitat is Unix file permissions — chmod 755 is three groups of three bits (read/write/execute). Decimal, meanwhile, remains what humans think in, which is why conversion back to decimal is the other everyday need.

Converting TO Decimal: Expand and Sum

The universal method for any base → decimal is the positional expansion:

0x2F  = 2×16 + 15     = 47
0b1010 = 1×8 + 1×2     = 10
0o755  = 7×64 + 5×8 + 5 = 493

For hex specifically, a useful reflex is knowing the “landmark” values: 0x10=16, 0x20=32, 0x40=64, 0x80=128, 0xFF=255, 0x100=256. Most hex you encounter is near one of these, so 0xF5 is “a bit less than 0xFF” ≈ 245 (it’s 245; check: 15×16+5). When you need an exact conversion fast, the Number Base Converter handles binary, octal, decimal, and hex in both directions.

Converting FROM Decimal: Divide and Collect Remainders

Decimal → any base uses repeated division by the target base; the remainders, read in reverse, are the digits:

247 ÷ 16 = 15 remainder 7   →  7
 15 ÷ 16 =  0 remainder 15  →  F
read bottom-up: 0xF7

For decimal → binary there’s a shortcut most developers prefer: subtract powers of two. Know the sequence 1, 2, 4, 8, 16, 32, 64, 128 cold. For 247: take 128 (119 left), take 64 (55), take 32 (23), take 16 (7), skip 8, take 4 (3), take 2 (1), take 1. Bits set at positions 7,6,5,4,2,1,0 → 11110111. Verify via hex: 11110111 = F7. ✓

Prefixes and Notation Across Languages

The same values wear different prefixes depending on context:

  • 0x or # prefix = hex (0xFF in C/Java/JS/Python, #FF5733 in CSS, FF5733 bare in many tools)
  • 0b = binary in most modern languages; 0B in some
  • Leading 0 = octal in C and JavaScript strict-mode-era legacy (0755); 0o in Python and modern JS (0o755)
  • \x in string escapes is hex ("\x41" is “A”), while \u introduces a Unicode code point in hex

Two traps: a bare leading zero makes 0755 octal in several languages, silently changing values (010 = 8); and octal-looking literals like 08 or 09 are flat-out invalid in strict mode. When in doubt, use explicit prefixes and verify with a converter.

Where This Shows Up in Real Work

  • Colors: #FF5733 is three bytes — converting color channels is hex↔decimal.
  • Permissions: chmod 755 is octal for bit groups; the chmod Calculator shows the bit mapping directly.
  • Character codes: ASCII A is 65 decimal = 0x41 = 0b01000001; the ASCII Table lists all three columns side by side.
  • Sizes and memory: file sizes mix decimal marketing units with binary hardware units — KB vs KiB — which is its own base-confusion story the Byte Converter untangles.
  • Bitwise flags: APIs that pack options as FLAG_A | FLAG_B are binary in disguise; reading flags & 0b0100 fluently means reading binary positions.

Quick Reference

  • Any base → decimal: expand digit × base^position and sum.
  • Decimal → any base: divide repeatedly, collect remainders bottom-up.
  • Hex ↔ binary: one hex digit = 4 bits, pure table lookup, no math.
  • Octal ↔ binary: one octal digit = 3 bits.
  • Landmarks: 0xFF=255, 0x100=256, 0b1000=8, 0755(octal)=493.
  • Prefixes: 0x hex, 0b binary, 0o/leading-0 octal (leading-zero form is a legacy trap).