Lesson 02 / 16
Hexadecimal and Octal Bases
Hexadecimal and octal representations, which give compact notation without breaking bit boundaries, and how to convert between them.
Contents
The previous lesson established that binary representation matches the hardware
exactly. That correspondence costs length: a 32-bit value is a thirty-two-symbol
sequence such as 01000001010000100100001101000100, and reading, writing, or
comparing this sequence without error is inconvenient for a person.
This lesson asks the following question: how can the same value be written with fewer symbols without hiding the bit structure? The answer lies in restricting the base choice to a power of two.
Why Powers of Two
If the base is chosen as , every digit in that base corresponds to exactly bits. This reduces conversion from computation to grouping: it suffices to split the bits into blocks of and replace each block with a single digit.
This does not hold for the decimal system, since is not a power of two. Looking
at the decimal digits of 4703 says nothing about its bit pattern; conversion
requires division. Hexadecimal and octal systems are therefore preferred: they give
compactness while doing so without breaking bit boundaries.
Hexadecimal System
In the hexadecimal system the base is . Sixteen digits are required; since the
ten symbols of the decimal system are insufficient, the letters A–F are used for
the remaining six values:
| Hex | Decimal | Binary | Hex | Decimal | Binary |
|---|---|---|---|---|---|
| 0 | 0 | 0000 | 8 | 8 | 1000 |
| 1 | 1 | 0001 | 9 | 9 | 1001 |
| 2 | 2 | 0010 | A | 10 | 1010 |
| 3 | 3 | 0011 | B | 11 | 1011 |
| 4 | 4 | 0100 | C | 12 | 1100 |
| 5 | 5 | 0101 | D | 13 | 1101 |
| 6 | 6 | 0110 | E | 14 | 1110 |
| 7 | 7 | 0111 | F | 15 | 1111 |
Since , every hexadecimal digit carries exactly four bits. A group of four bits is called a nibble. A byte is eight bits, that is, two nibbles; every byte is therefore written with exactly two hexadecimal digits. This is the real reason for the widespread use of hexadecimal notation: byte boundaries remain visible in the representation.
Whether the letters are written in upper or lower case does not change the value;
0xFF and 0xff denote the same value. Within a single text, one form is chosen for
consistency.
Converting by Grouping
To go from binary to hexadecimal, the bits are grouped in fours starting from the right, and each group is replaced by its counterpart in the table. If the leftmost group has fewer than four bits, it is padded with leading zeros.
A thirty-two-bit sequence collapses to eight hexadecimal digits: 41424344. The
reverse direction applies the same rule in the opposite order: each hexadecimal digit
is replaced by four bits.
Grouping from the right matters. Grouping from the left, when the bit count is not a multiple of four, shifts every positional value and produces an incorrect result.
The Course’s Shared Example
The value obtained above is the example this course will return to again and again:
Its decimal counterpart can be computed from the positional values:
This is the interpretation of the 32-bit pattern as an unsigned integer. The same pattern will be interpreted differently in later lessons: as a signed integer, as a real number, as a four-letter piece of text, and as a sequence that looks different depending on the byte order in memory. The bit pattern stays the same across all these readings; what changes is only the interpretation rule applied to it.
This distinction carries the central idea of the lesson about the nature of data: memory contains no such thing as a “number” or “text” — it contains bit patterns and the interpretations applied to them.
Octal System
In the octal system the base is ; the digits range from to . Since , every octal digit carries three bits, and conversion again proceeds by grouping — this time in threes.
Because groups of three do not align with byte boundaries, octal representation lags behind hexadecimal for general-purpose use: 8 bits, grouped in threes, yield two full digits and two leftover bits.
Octal survives in domains whose natural unit is three bits. File permissions on
Unix-derived systems are the standard example: read, write, and execute permissions
form a group of three bits, and this group is repeated separately for owner, group,
and others. The notation 755 encodes the permission rwxr-xr-x; the first digit
states that all three permissions are granted, and the other two digits
state that write permission is off. The permission model is treated in
detail in the Linux curriculum.
Notational Conventions
Which base a number is written in must be stated in code just as it is in text. Common prefixes:
| Prefix | Base | Example | Value |
|---|---|---|---|
0b |
2 | 0b1011 |
11 |
0o |
8 | 0o755 |
493 |
0x |
16 | 0x1F |
31 |
| (none) | 10 | 31 |
31 |
Prefixes are not part of the value; they only state which base to read. When the same value is written in four different forms, the same bit pattern results in memory.
The following program shows the conversions and formatting:
value = 0x41424344 print(value) # 1094861636 print(hex(value)) # 0x41424344 print(bin(value)) # 0b1000001010000100100001101000100 print(f"{value:#010x}") # 0x41424344 (at least 8 digits, prefixed) print(f"{value:032b}") # 01000001010000100100001101000100 # Reading byte by byte: each byte is two hexadecimal digits. for shift in (24, 16, 8, 0): byte = (value >> shift) & 0xFF print(f"{byte:#04x}", byte) # 0x41 65 / 0x42 66 / 0x43 67 / 0x44 68
It is worth noting that the bin output has 31 digits rather than 32: the built-in
function does not print leading zeros. When fixed-width representation is required, a
format specifier (032b, #010x) is used. Fixed width is needed to keep columns
aligned when memory contents are inspected.
The >> and & operators in the loop extract a specific byte from the pattern; these
operators will be defined in the lesson on bit-level operations.
Summary
- When the base is chosen as , conversion between bases is not computation but grouping in blocks of .
- In the hexadecimal system every digit carries four bits, so every byte is exactly two digits; byte boundaries remain visible in the representation.
- Converting binary to hexadecimal groups from the right; a leftover left group is padded with zeros.
- In the octal system every digit is three bits; because it does not align with byte boundaries, its use is limited to naturally three-bit fields such as file permissions.
- The
0b,0o,0xprefixes state the base to be read, not the value. - The course’s shared example,
0x41424344, has the value under an unsigned interpretation.
Next Step
Up to this point every number has been treated as non-negative. Hardware, however, has no separate place to hold a minus sign; the sign, too, must be encoded within the bit pattern. The next lesson takes up how this is done, and why the chosen method leaves the addition circuit unchanged.
To keep your progress and take notes, Log in
My notes
Log in to take notes.