Welcome to Counting with Computer 101. Have you ever looked at a colour on a computer and seen something like this #28FE9A? Or perhaps the T-shirt stating ‘There are 10 types of people in this world, those who understand binary, and those who don’t’ leaves you nonplussed. Both of these examples are classic cases of the translation barrier between the way that humans count, and the way a computer counts. Understanding the way that hexadecimal and binary counting systems work is essential to working with everything from microcontrollers, to colour palettes. But first, let’s recap how our decimal counting system actually works:
Decimal
The decimal counting system comes from the greek prefix ‘dec’ meaning ten. This makes sense to us because humans have 10 fingers to count on, and thus we developed ten digits in which to count: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. If you can recall back to when you first learned maths in primary school, we were taught that from 0-9 we are counting in the ‘ones’ column, but 9 is the biggest single digit that we have, so we increment our next column, ‘tens’ to one, and then reset our ‘ones’ column back to 0.
This method of counting makes a lot of sense to us because we can count it on our fingers, and to increment to the next unit, we simply add a 0 to the end, and we’ve multiplied by 10 and gone from ones to tens, or tens to hundreds etc.
This is great for us, but completely counter to the way a computer works. A computer doesn’t think between 0-9, it thinks in either ON or OFF, HIGH or LOW, 1 or 0. This is due to the way that the silicon hardware works, a transistor can either turn on or off, it can’t be in between. Which brings us to the binary counting system.
Binary
Binary is the most basic of counting systems, and the way that computers function. Everything from the pixels you’re reading right now, to complex maths, can be boiled down to a lot of 1’s and 0’s. A lot.
So now we understand the way that units and columns work, it is easier to understand that instead of 0-9 possible values, binary allows for two values, 0 and 1. This means that when we get to 1, instead of incrementing to 2, we create a new column with a 1 in it, and reset the previous column to 0.
What this means is that each column is allocated the value of 2 to the power of whatever digit you are up to (starting from 0). Then we multiply that 2n by the 1 or 0 that occupies that column. A 1 means it is equal to the power (1x22 = 4) and a 0 means it is ignored in the number (0x22 = 0). This might sound confusing, but once you understand logical foundation of binary, converting between binary and decimal becomes quite easy.
When dealing with binary, a single binary digit is called a bit (short for binary digit) and a group of bits is called a byte (usually 8 bits). A binary number is usually denoted by the 0b prefix before it.
To start with, let’s us a 3 bit binary number and look at the way it increments.
Now let’s take a look at the 8-bit byte below:
To work out the value of this binary byte, start with the number to the left (although since we’re adding them all together it doesn’t really matter where you start) and put in the decimal value into each column, calculating the 1’s and ignoring the 0’s.
Can you see the pattern emerging? If we add all those values together, we get our binary value for that byte. It equals:
(1x27)+(0x26)+(1x25)+(0x24)+(1x23)+(1x22)+(1x21)+(0x20) = 246
The maximum range for an 8-bit binary number is 256 values or 0-255. A 10-bit binary number for example, as found on microcontroller ADCs ranges between 0-1023.
If you’ve ever encountered an RGB colour mixer before, you might be looking at the 8-bit 0-255 range and thinking it looks familiar. You’re not wrong. An RGB number uses one byte for Red, another for Green, and another for Blue giving each colour channel a range between 0-255.
Binary is awesome and all, except using 8 digits to represent a standard byte can get arduous, and there are more efficient ways to represent numbers in a way that computers can still understand. Drum roll for………….
Hexadecimal
‘What?!’ I hear you say? If computers work best in binary, why do we need to use another counting system? It’s a great question and there are a few different reasons why hexadecimal is commonly used in computing systems.
Hexadecimal is much easier for humans to interpret than binary, its closer to our base 10 counting logic than binary is. It’s also requires far less digits to represent a number than both binary and decimal, and isn’t overly hard for computers to understand.
Before we can take a look at why hexadecimal is great to use, we need to understand how it works first. Our plain old decimal system is known as base-10 counting, binary is known as base-2 counting, and hexadecimal is known as base-16 counting. Instead of stopping at 9 (our 10th unique digit) to increment the next column, hexadecimal uses 16 unique digits to represent the numbers 0-15. Except we only have 0-9, so we use A, B, C, D, E, and F for the numbers 10-15. Hexadecimal is represented with either ‘0x’ or ‘h’ before the number.
Instead of writing 12 in decimal, requiring two digits, we can just write ‘C’ (0xC with the hex prefix). However the big advantage of hex is when converting it from binary. Remember how a standard byte consists of 8 byte? Well if we split that byte up into two groups of 4 bits; 0000 0000 then we get two lots of numbers which have a maximum range of 0-15, which is perfect for base-16.
This allows us to represent the first four bits (high bits) with one hex digit, and the second four bits (low bits) with a second hex digit. Efficient huh?
Thus instead of using 0b00000000 (binary), we can use 0x00 (hex). A binary value of 0b00001111 is equal to 15 in decimal, and 15 is equal to F in hex, so 0b00001111 is equal to 0x0F.
A few examples:
As you can see, it becomes quite easy to convert an 8-bit byte from binary to hexadecimal by breaking the byte up into 4-bit groups and converting each group into a hexadecimal digit.
We mentioned above that RGB colour mixers represent Red, Green, and Blue each as a single byte, well that’s great, but it takes up 24 digits in binary. Far simpler is expressing these values in hex. A hex colour comes in the format of #FFFFFF (that would be white) where the first two digits represent the Red channel, the second two represent the Green channel, and the last two represent the Blue channel.
Awesome, What Now?
Cool beans, now we have no fear of numbers that looking like this: 0xFB89D2 or even this: 0b11000101. We can convert to and from base-10, base-2, and base-16. Go forth and write to registers, calculate colours, and define variables with ease!