Hexadecimal

Base 16, converting to binary and denary, and the LED's colour codes.

F8.3Data representationGCSE15 min

Covers OCR J277 1.2.4 Data storage · AQA 8525 3.3.2 Converting between number bases · Edexcel 1CP2 2.1.6 Hexadecimal

Do this lesson in the simulator

Binary is what the computer uses, but it is long and easy to misread: 11111111 10000000 00000000 is one colour. Hexadecimal, or hex, is base 16, and it writes the same value in a quarter of the digits: FF8000. Web colours, error codes and network addresses are all written in hex, and so is the robot's LED.

Sixteen digits

Hex needs sixteen digits, so after 0 to 9 it uses the letters A to F:

Denary 0 1 ... 9 10 11 12 13 14 15
Hex 0 1 ... 9 A B C D E F
Binary 0000 0001 ... 1001 1010 1011 1100 1101 1110 1111

One hex digit stands for exactly four bits, a nibble. That is what makes hex so useful: every byte is exactly two hex digits.

Binary and hex

Split the byte into two nibbles and convert each:

1011 0110
  B    6    ->  B6

And back again: each hex digit becomes four bits. 3F is 0011 1111.

The byte 10110110 split into two nibbles: 1011 is 8 + 2 + 1 = 11, which is B, and 0110 is 4 + 2 = 6left nibble842110118 + 2 + 1 = 11Bright nibble842101104 + 2 = 66and
Each nibble is worked out on its own with the place values 8, 4, 2 and 1, and gives one hex digit. 11 is written B, so the byte is B6.

Hex and denary

In a two-digit hex number, the left digit is worth 16 and the right digit is worth 1. So B6 is 11 × 16 + 6 = 182. The other way, divide by 16: 182 ÷ 16 is 11 remainder 6, so B6.

B6 in place-value columns: B is 11 sixteens, 176, and 6 is 6 ones, which add up to 18216sixteensB1ones6B is 116 is 611 × 16 = 1766 × 1 = 6176 + 6 = 182the other way: 182 ÷ 16 = 11 remainder 6, so B6
The same place values as denary and binary, but each column is worth 16 times the one on its right. Dividing by 16 goes back: the answer is the left digit and the remainder the right one.
# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

DIGITS = "0123456789ABCDEF"

def to_hex(n):
    """0 to 255 -> two hex digits."""
    return DIGITS[n // 16] + DIGITS[n % 16]

def from_hex(h):
    """two hex digits -> 0 to 255."""
    return DIGITS.index(h[0].upper()) * 16 + DIGITS.index(h[1].upper())

for n in [182, 255, 16, 9]:
    print(n, "->", to_hex(n), "->", from_hex(to_hex(n)), "check:", format(n, "02X"))

Run this in the simulator

n // 16 and n % 16 split the number into the sixteens and the ones, exactly as the method says.

Colours in hex

A colour on screen, and on BugBot's LED, is three bytes: red, green and blue, each 0 to 255. Written in hex, that is six digits after a #:

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

colours = ["#FF0000", "#00FF00", "#0000FF", "#FF8000", "#8000FF", "#FFFFFF"]
for code in colours:
    print(code)
    led(code)
    wait(0.5)
led("off")

Run this in the simulator

#FF8000 is red FF (255), green 80 (128), blue 00 (0): orange. Try inventing colours by changing the digits, then predict the colour before you run it.

The colour #FF8000 is three bytes: red FF is 255, green 80 is 128 and blue 00 is 0#redFF1111 111115 × 16 + 15= 255fullgreen801000 00008 × 16 + 0= 128about halfblue000000 00000 × 16 + 0= 0nonebitshow muchfull red + half green = orange
Each pair of hex digits is one byte, one colour of light from 0 to 255. Full red with half as much green and no blue is orange.

Why hex?

  • Shorter than binary, so it is quicker to read and write.
  • Fewer mistakes: B6 is much harder to mistype than 10110110.
  • Easy to convert to binary, because each digit is exactly four bits, unlike denary.

Hex is only for people. The computer still stores the binary.

Task: mix a colour

Write to_hex(n) yourself (no hex or format) that turns 0 to 255 into two hex digits. Use it to build the colour code for red 255, green 128, blue 64, print it as #FF8040, and show it on the LED by passing your code to led.

# the two lines every program starts with: the commands, then the robot
from bugbot import *
connect()

DIGITS = "0123456789ABCDEF"

def to_hex(n):
    return "00"

Challenges

  1. Write rgb(code) that turns "#FF8040" back into the three numbers.
  2. Fade the LED from black to white in 16 steps, printing each hex code.
  3. What is the largest number three hex digits can hold? Work it out, then check with int("FFF", 16).