Hexadecimal
Base 16, converting to binary and denary, and the LED's colour codes.
Do this lesson in the simulatorBinary 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.
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.
# 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"))
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")
#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.
Why hex?
- Shorter than binary, so it is quicker to read and write.
- Fewer mistakes:
B6is much harder to mistype than10110110. - 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
- Write
rgb(code)that turns"#FF8040"back into the three numbers. - Fade the LED from black to white in 16 steps, printing each hex code.
- What is the largest number three hex digits can hold? Work it out, then check with
int("FFF", 16).