Skip to main content

Number Base Conversion Cheatsheet for Developers: Hex, Binary, and Octal

A practical cheatsheet covering hex, binary, and octal conversion for developers. Real tables, working examples, and the mental shortcuts I use daily.

Published
#hex #binary #octal #number-bases #developer-tools #cheatsheet

Number Base Conversion Cheatsheet for Developers: Hex, Binary, and Octal

Every developer hits the moment where a stack trace prints 0x7ffee4b2c3a0 and they need to know what that actually means. Or a bitfield spec says "set bits 3–5" and the register map is in hex. Or a Unix file permission shows 0755 and the mental model breaks.

This cheatsheet is the reference I keep going back to — the tables, the conversion patterns, and the quick mental shortcuts that actually stick.

Why Hex, Binary, and Octal Exist Together

The three bases aren't arbitrary. They each fit a job the hardware already does:

  • Binary (base 2) mirrors how transistors work: on or off. Every CPU, memory cell, and protocol frame at the physical layer is binary.
  • Hexadecimal (base 16) compresses binary neatly. Every 4 bits maps to one hex digit exactly, so a 32-bit value is always 8 hex characters — no rounding, no conversion overhead.
  • Octal (base 8) groups bits in threes, which maps cleanly to Unix permission triads: owner, group, world, 3 bits each. That is the only reason octal still shows up in everyday code.

The key relationship: a 4-bit nibble becomes one hex digit; a 3-bit group becomes one octal digit. That clean mapping is why these bases exist alongside decimal instead of, say, base 12.

The Core Conversion Table (0–255)

Below is the cheatsheet range developers reference most often — values 0 through 15, which cover a single nibble, and a handful of milestones above that.

| Decimal | Hex | Binary | Octal | |---------|------|-----------|-------| | 0 | 0x00 | 0000 | 0 | | 1 | 0x01 | 0001 | 1 | | 2 | 0x02 | 0010 | 2 | | 3 | 0x03 | 0011 | 3 | | 4 | 0x04 | 0100 | 4 | | 5 | 0x05 | 0101 | 5 | | 6 | 0x06 | 0110 | 6 | | 7 | 0x07 | 0111 | 7 | | 8 | 0x08 | 1000 | 10 | | 9 | 0x09 | 1001 | 11 | | 10 | 0x0A | 1010 | 12 | | 11 | 0x0B | 1011 | 13 | | 12 | 0x0C | 1100 | 14 | | 13 | 0x0D | 1101 | 15 | | 14 | 0x0E | 1110 | 16 | | 15 | 0x0F | 1111 | 17 | | 16 | 0x10 | 0001 0000 | 20 | | 32 | 0x20 | 0010 0000 | 40 | | 64 | 0x40 | 0100 0000 | 100 | | 127 | 0x7F | 0111 1111 | 177 | | 128 | 0x80 | 1000 0000 | 200 | | 255 | 0xFF | 1111 1111 | 377 |

Notice that 0xFF in hex equals 377 in octal and 255 in decimal — the same value, three different notations. Also notice that octal 377 ends at an exact power of 8 boundary: 8³ = 512, so 377 octal = 255 decimal makes visual sense.

For quick mental arithmetic, there is a useful benchmark: a 32-bit IPv4 address always fits in exactly 8 hex digits. 192.168.0.1 becomes 0xC0A80001 — the two formats encode identical information, and hex is roughly 28% shorter (10 characters vs 14 in dotted-decimal form, counting the "0x" prefix). That is why network debuggers default to hex output.

How to Convert Without a Calculator

Decimal → Hex

Divide by 16 repeatedly, record each remainder as a hex digit (10=A, 11=B, … 15=F), read remainders bottom to top.

437 ÷ 16 = 27  remainder 5   → digit '5'
 27 ÷ 16 =  1  remainder 11  → digit 'B'
  1 ÷ 16 =  0  remainder 1   → digit '1'

Result: 0x1B5

Check: 1×256 + 11×16 + 5 = 256 + 176 + 5 = 437

Hex → Binary

Replace each hex digit with its 4-bit group directly — no arithmetic needed.

Input:  0x4A3F
  4 → 0100
  A → 1010
  3 → 0011
  F → 1111

Output: 0100 1010 0011 1111

This is the conversion I use constantly. The 4-bit groups for the hex alphabet are fixed, so it is lookup, not calculation.

Binary → Octal

Group the bits into chunks of 3 from the right, then convert each chunk.

Input:  110 111 010

  110 → 6
  111 → 7
  010 → 2

Output: 0672 (octal)

Real-World Situations Where Each Base Appears

Hex in practice:

  • Memory addresses in debuggers and stack traces
  • Color codes in CSS: #FF6B35 means R=255, G=107, B=53
  • SHA-256 hashes: a 256-bit value shown as 64 hex digits
  • Protocol headers: HTTP/2 frames, TLS record headers

Binary in practice:

  • Bitfield manipulation in C/C++/Rust — reading flags, setting individual bits
  • Network subnets: /24 means 24 bits are 1 in the mask, so the binary mask is 11111111.11111111.11111111.00000000
  • IEEE 754 float anatomy: 1 sign bit + 8 exponent bits + 23 fraction bits

Octal in practice:

  • Unix file permissions: chmod 755 means rwxr-xr-x — the three digits are three 3-bit groups (7=111, 5=101, 5=101)
  • Older network protocols and POSIX API constants still use octal literals in C headers (O_RDONLY = 0, O_WRONLY = 01, O_RDWR = 02)

Mental Shortcuts That Actually Stick

I've been doing embedded and backend work for a while, and three shortcuts reduced most of my mental overhead:

1. The 8/A/F anchors. Memorize just three hex-to-decimal mappings: 0x8 = 8, 0xA = 10, 0xF = 15. Any other nibble is reachable by counting up or down from one of these. 0xD = 0xF - 2 = 13. 0xB = 0xA + 1 = 11.

2. High bit = 0x80 = 128. When you see the most-significant bit set in a byte (0x80 and above), the value is ≥ 128. This matters for two's complement sign detection and for UTF-8 multi-byte sequences, which always start with a byte ≥ 0xC0.

3. Power-of-two boundaries in hex. 0x100 = 256, 0x400 = 1024 (1 KiB), 0x1000 = 4096 (one 4K page). Knowing these means you can size memory regions and offsets quickly without touching a calculator.

For anything beyond mental arithmetic, I use Toolora's base converter, which converts between any two bases from base 2 to base 36 with a single input field. When working with binary arithmetic — especially when I need to verify that a two's complement subtraction gives the right result — the binary calculator handles 200-bit exact integers, which is more precision than Python's int display ever confused me into needing.

Common Mistakes to Avoid

Confusing octal literals in source code. In C, JavaScript, and Python 2, a leading zero signals an octal literal: 0755 is octal 755, not decimal 755. Decimal 755 = 0x2F3 in hex. Python 3 fixed this by requiring 0o755 for octal, but older code — and shell scripts using chmod — still uses the bare 0 prefix.

Off-by-one errors with nibble boundaries. A 3-character hex string like 0xFFF represents 12 bits, not 16. Hex digits always come in pairs for byte-aligned data. If your hex string has an odd number of digits, it is either left-padded with a zero or something is wrong with the source.

Signed vs. unsigned interpretation. 0xFF as an unsigned byte is 255. As a signed 8-bit integer it is −1 (two's complement: flip bits → 0x00, add 1 → 0x01, negate → −1). Debuggers usually let you toggle between unsigned and signed views; make sure you know which one you are looking at.


Made by Toolora · Updated 2026-06-27