Hex and Octal

Compact notations for binary data — hexadecimal groups bits into fours, octal into threes, making long bit strings human-readable.

Why This Matters

Binary is the native language of digital hardware, but strings of 0s and 1s are tedious to read and write. A single byte requires eight binary digits. A memory address in a 16-bit system needs sixteen binary digits. Errors in transcription are frequent.

Hexadecimal and octal solve this problem by providing compact shorthands for binary. Hex is now dominant because it aligns perfectly with 4-bit nibbles and 8-bit bytes. Octal, which groups three bits at a time, was widely used in the minicomputer era (PDP systems, Unix permissions) and remains relevant for understanding file permissions and legacy code.

Fluency with hex-binary conversion is a core competency for anyone working with hardware registers, machine code, memory maps, or network protocols. It is the difference between reading a register dump as meaningful data versus an incomprehensible string of digits.

Hexadecimal: Grouping by Fours

Hexadecimal (base 16) uses 16 symbols: 0–9 for values zero through nine, and A–F for values ten through fifteen. One hex digit represents exactly four binary bits (a nibble).

Correspondence:

BinaryHexDecimal
000000
000111
001022
001133
010044
010155
011066
011177
100088
100199
1010A10
1011B11
1100C12
1110E14
1101D13
1111F15

Hex numbers are prefixed with 0x (in C/assembly), FF, or FFH all mean 255.

Binary-to-Hex Conversion

Group binary bits in fours from right to left, then convert each group using the table.

Example: convert binary 1011 0110 1101 0010

  • Split: 1011 | 0110 | 1101 | 0010
  • Convert each group: B | 6 | D | 2
  • Result: 0xB6D2

Example with a number not divisible by 4 bits: 10110111

  • Split from right: 1011 | 0111
  • Convert: B | 7
  • Result: 0xB7

Pad with leading zeros if needed to complete the leftmost group.

Hex-to-Binary Conversion

Replace each hex digit with its 4-bit binary equivalent.

Example: convert 0x3A9F

  • 3 = 0011
  • A = 1010
  • 9 = 1001
  • F = 1111
  • Result: 0011 1010 1001 1111

This is completely mechanical — no arithmetic needed. Write each digit’s 4-bit code in sequence.

Hex-to-Decimal Conversion

Use the place-value method: each position is a power of 16.

0x3A9F:

  • F (position 0) = 15 × 16^0 = 15
  • 9 (position 1) = 9 × 16^1 = 144
  • A (position 2) = 10 × 16^2 = 2,560
  • 3 (position 3) = 3 × 16^3 = 12,288
  • Total: 15 + 144 + 2,560 + 12,288 = 15,007

For quick mental conversion, use the iterative method: start with the leftmost digit, multiply by 16, add next digit, repeat. 0x3A: 3 × 16 = 48, + 10 = 58. Check: 58 decimal = 0x3A. ✓

Octal: Grouping by Threes

Octal (base 8) uses digits 0–7. One octal digit represents exactly three binary bits.

BinaryOctal
0000
0011
0102
0113
1004
1015
1106
1117

Octal is denoted with a leading 0 in C (0755) or the suffix O. The notorious Unix file permission 0755 means: owner=rwx (111=7), group=r-x (101=5), world=r-x (101=5).

Convert binary to octal by grouping from right in threes: 11 010 111 → 3, 2, 7 → octal 327

Octal was preferred on machines with 12-bit or 18-bit word sizes (evenly divisible by 3), where hex does not align naturally. For 8-bit and 16-bit machines, hex is better since bytes align on 2-hex-digit boundaries.

Hex Arithmetic

Adding hex numbers: use standard positional addition. Carry when sum exceeds F (15).

0x7A + 0x6B:

  • Units place: A + B = 10 + 11 = 21 = 0x15, write 5, carry 1
  • 16s place: 7 + 6 + 1(carry) = 14 = 0xE
  • Result: 0xE5

This is useful for mental calculation of memory addresses: base address 0x8000 plus offset 0x200 = 0x8200.

Common Hex Values to Memorize

Knowing these by heart speeds up register and address analysis:

  • 0xFF = 255 = all 8 bits set = full byte mask
  • 0x0F = 15 = low nibble mask
  • 0xF0 = 240 = high nibble mask
  • 0x80 = 128 = bit 7 set (sign bit of signed byte)
  • 0x100 = 256 = 2^8 (one byte overflow)
  • 0xFFFF = 65535 = full 16-bit word
  • 0x10000 = 65536 = 2
  • 0x7FFF = 32767 = maximum positive signed 16-bit integer
  • 0x8000 = 32768 = minimum (most negative) signed 16-bit integer