I'm going old-school here, but some of these basics are overlooked nowadays. This is not a post for my Ruby on Rails friends, but rather for folks who may be learning low-level programming.
Why Hex?
Hexadecimal ("hex" from now on) is just a shorthand binary notation. We don't use normal decimal numbers because they don't line up with their binary equivalents.
All modern computers have a word size that is 8 times a power of 2. Simply stated, it will be 8, 16, 32, or 64 bits. There have been computers with larger word sizes, and there have been computers with weird word sizes.
The DEC PDP-6 was a 36-bit computer. I have worked on a CDC 830 which used a 60-bit word size. Each of these had the capability of storing 6-bit characters in their words.
There's something interesting about those word sizes - they also have "3" as a factor.
Back when I was a kid, octal was more popular than hex when handling binary data. For a 36-bit computer, each word is 12 octal digits and those line up nicely with the bits. Things get messy when dealing with modern word sizes and octal. Why?
Consider what "all bits on" looks like:
Binary: 1111 1111
Octal: 377
Binary: 1111 1111 1111 1111
Octal: 177777
Binary: 1111 1111 1111 1111 1111 1111 1111 1111
Octal: 37777777777
Hopefully you can see the issue here. It's not obvious what octal digits line up to what binary digits.
You'll notice that I spaced out the bits into groups of four bits each. 8 bits is a byte, and 4 bits is a nybble (pronounced as "nibble"). This is common in any literature to make things more readable. And, luckily, each nybble corresponds to a hex digit.
Hex to the Rescue
Hexadecimal is just a base-16 number system. We have our normal 10 digits in base 10 - 0 through 9 - so for hex we just add a-f to represent the numbers 10-15 in decimal. Hex is really easy:
Decimal | Hex | Binary |
---|---|---|
0 | 0 | 0000 |
1 | 1 | 0001 |
2 | 2 | 0010 |
3 | 3 | 0011 |
4 | 4 | 0100 |
5 | 5 | 0101 |
6 | 6 | 0110 |
7 | 7 | 0111 |
8 | 8 | 1000 |
9 | 9 | 1001 |
10 | A | 1010 |
11 | B | 1011 |
12 | C | 1100 |
13 | D | 1101 |
14 | E | 1110 |
15 | F | 1111 |
It's identical to decimal until we get to "10", and we start using those letters. "F" is all four bits on, "0" is all four bits off.
So, again, hex is just a way to write binary that's shorter and often more readable.
Memorizing Bit Patterns
You can think of each hex digit as the corresponding bit pattern, and if you're going to do any low-level programming you really want to be able to have the above table memorized. Here's how I did it.
Comments | Binary | Hex | Decimal |
---|---|---|---|
No bits | 0000 | 0 | 0 |
All bits | 1111 | F | 15 |
One bit | 0001 | 1 | 1 |
0010 | 2 | 2 | |
0100 | 4 | 4 | |
1000 | 8 | 8 | |
Two bits - outer | 1001 | 9 | 9 |
Two bits - inner | 0110 | 6 | 6 |
Two bits - ends | 1100 | C | 12 |
0011 | 3 | 3 | |
Two bits - spaced | 1010 | A | 10 |
0101 | 5 | 5 | |
Three bits - ends | 1110 | E | 14 |
0111 | 7 | 7 | |
Three bits - space | 1011 | B | 11 |
1101 | D | 13 |
That's it. Remember those patterns and you'll be able to "see" the bits and vice versa.
Advanced Hex
One other thing - now and then you need to know certain numbers in decimal. You should have powers of two memorized up to 65,536, along with the corresponding 2^x-1. You should also know the factors of 16 up to 16*16. For instance, if I see "C0" I know that's 192 decimal because "12 * 16" is 192 in decimal.
This isn't for everybody. If you're a web programmer it's unlikely that you'll need to care about any of this.
On the other hand, if you're reading spec sheets for a piece of hardware, you'll need every bit of this.
Enjoy, and ask questions below.
Top comments (0)