11110000 in binary is F0 in hexadecimal. Both mean 240. Hex gives each group of
four bits one digit, making a long row of switches easier to read.
A bit is one binary digit: 0 or 1, like a switch that is off or on. A byte is eight bits. In binary, the positions count 1, 2, 4, 8 and so on from right to left; add the values of the positions containing a 1 to get the number.
11111111 — quick, how many ones? You had to count. Binary tells the whole truth, but
eight switches is more than you can take in at a glance, and programmers look at these all
day. They wanted a shorthand that still showed the bits. That shorthand is hexadecimal.
Decimal hides the bits
Why not read the byte in ordinary tens? Because decimal does not line up with switches.
11111111 is 255. The decimal number does not directly show which switches are on.
Turn off the rightmost bit, worth 1, and you get 11111110, or 254. The decimal barely
moves, while the bit pattern changed in a clear, specific place.
We want a shorthand where the writing still shows the switches. Grouping the bits in fours gives us one.
Group the bits in fours
Split a byte down the middle into two halves of four bits. Four bits has its own name. It is a nibble, which is half a byte.
How high does one nibble count? Turn all four on:
The examples use pseudocode to show the calculation, not commands to type into a
Spectrum. SHOW displays a value, and BIN says the following digits are binary.
SHOW BIN 111115
A nibble runs 0 to 15, which is sixteen values. That is the whole idea of hex: give each nibble a single symbol, so four bits become one character.
Sixteen needs sixteen symbols
Here is the snag. We have ten digits, 0 to 9. Sixteen values need sixteen symbols, so hex borrows the first six letters for the values past nine. A is ten, B is eleven, and so on up to F for fifteen.
| Bits | Decimal | Hex |
|---|---|---|
| 0000 | 0 | 0 |
| 0101 | 5 | 5 |
| 1001 | 9 | 9 |
| 1010 | 10 | A |
| 1100 | 12 | C |
| 1111 | 15 | F |
So A to F are not letters here. They are digits, the ones we ran out of symbols for. F
means a full nibble, all four on.
Group a shorter pattern
For a shorter pattern, start grouping from the right. BIN 101101 becomes
0010 1101 when we add leading zeros on the left. Those groups are 2 and D,
so the result is HEX 2D, or 2 × 16 + 13 = 45. It is the same pattern
we built from 32 + 8 + 4 + 1.
Padding on the right would change the number: 10110100 is 180, not 45.
Leading zeros preserve a value; extra zeros on the right move its place values.
A byte is two hex digits
Two nibbles make a byte, so we can write any byte using two hex digits. Keep a
leading zero when needed: five becomes 05. In our pseudocode, HEX marks a
hexadecimal value, just as BIN marks a binary one:
SHOW BIN 11111111
SHOW HEX FF255 255
Both lines came to the same number, because they are the same number written two ways. F
on the left is the high nibble, worth fifteen sixteens. F on the right is the
low nibble, worth fifteen ones: 15 × 16 + 15 = 255.
Now watch what hex shows that decimal hid. Turn the low nibble off and leave the high one on:
SHOW BIN 11110000
SHOW HEX F0240 240
In decimal, 255 became 240. That jump hides what happened. In hex it went FF to F0, and
the change is right there in the second digit. The low nibble emptied.
That is hex’s whole appeal. Each digit is one nibble, so you read the bits straight off.
When a digit runs out
Ordinary counting in hex carries into the next place:
SHOW HEX 0F + 1
SHOW HEX FF + 116 256
Those results are HEX 10 and HEX 100. The first fits in two hex digits;
the second needs three. A chosen unsigned byte still holds only 00 through FF.
This is a calculation with numbers, not a promise that an eight-bit storage
operation keeps all the digits. A target lesson must state its range rule.
Do HEX 10 and decimal 10 mean the same value? Which fits in an unsigned byte: HEX FF or HEX 100?
HEX 10 means 16, while decimal 10 means ten. HEX FF is 255 and
fits; HEX 100 is 256 and does not. Writing HEX 0100 adds a leading
zero but leaves that value at 256. The base and the chosen width answer
different questions.
Why programmers reach for it
- It lines up with bits. One hex digit is exactly four switches.
- It is short. A byte is two characters instead of eight.
- It is common. Memory addresses, colour values and the bytes of machine code are often written in hex, because hex shows the bits.
Not every language writes it the way we have. Most use a marker in front of the digits
instead of a word, and $F0 and 0xF0 are the two you will meet most.
When it’s wrong, see why
- A hex digit above F. There is not one. Hex runs 0–9 then A–F and stops. A “G” is not a hex digit.
- Reading hex
10as ten. It is 1 × 16 + 0 = sixteen. In a two-digit hex number, the left digit counts in sixteens. That is exactly why the base gets marked, by a word likeHEXor a sign like$. - Mixing up the halves. The left hex digit is the high nibble, the right is the low one. The left digit counts in sixteens; the right counts in ones.
What you’ve learnt
- Hex is base sixteen: one symbol per nibble, so four bits become one character.
- Counting runs 0–9 then A–F, and the letters are the digits past nine.
- We can write a byte in two hex digits, 00 to FF.
FFis 255, with all eight bits on. - Hex earns its keep because it shows the bits where decimal hides them.
See the pattern do a job
A byte becomes pixels
shows a complete Spectrum program that uses one bit per pixel. Its % marks
binary and its $ marks hex; read the local explanation without learning
assembly first. Running or changing that program is optional.
For a numerical use of the same bits, Two bytes together builds a larger unsigned value and separates an address range from installed memory.
What’s next
A byte runs out at 255, and a game needs bigger numbers than that before the first level is over. In Unit 3 we put two bytes side by side, and hex turns out to have been ready for it.