A Number by Any Other Name

OK, back to the CS stuff…

Back before the current "challenging times" began, we were talking about how computers store numbers in memory. We left with an example of storing the number 1,456 in memory, and stated that we would need two bytes of memory to store it:

To figure out what is in the 256’s place of our computer number, we divide 1,456 by 256, which is 5 with a remainder of 176. So we store 5 in the 256’s place, and 176 in the ones place:

Memory 256’s Ones
5 176

However, a computer programmer or coder would not write this as 5, 176. They would actually write it as 0x05B0.

Wait, Oh Ex Oh what now? What the heck is that?

All Your Bases

Back a while ago, we were talking about why the number 255 was special. I mentioned that computer memory at it’s heart is just a series of switches that can turned on and off. A switch which is on represents the digit one, and a switch that is off represents the digit zero.

If we only use two individual digits to represent all our numbers, we say we are using the binary number system. In a more mathematical sense, we can say we are working with a different number base, in this case, base 2. In base 2, we only use two different symbols to represent all numbers, namely 0 and 1.

Compare this to the numbers you are accustomed to using, which use ten individual digits to represent all our numbers. This is called the decimal number system, or base 10, where we use ten different symbols to represent all numbers.

These aren’t the only two number systems you can use. While you can use any number base you want, it turns out that one other number system works exceptionally well for computers: base 16, also called hexadecimal.

What makes hexadecimal (or hex, for short) so good for representing numbers in a computer? We’ll take a look at some of the properties of hex to explore why, but first, let’s define what hex is first, and how to write a number in hex.

Hexed

First, hex requires sixteen different symbols to represent all numbers because it’s base 16. Hex uses the ten digits from zero through nine conventionally, but for the remaining six, it uses the first six letters of the English alphabet.

0 1 2 3 4 5 6 7 8 9 A B C D E F

So what exactly is the value of A? Since each digit is one more than the digit before it, and A comes after 9, the value of A is 10. Let’s look at a chart comparing hex, decimal, and binary numbers:

Hex 0 1 2 3 4 5 6 7
Decimal 0 1 2 3 4 5 6 7
Binary 0000 0001 0010 0011 0100 0101 0110 0111
Hex 8 9 A B C D E F
Decimal 8 9 10 11 12 13 14 15
Binary 1000 1001 1010 1011 1100 1101 1110 1111

So how do you convert the decimal number 1,456 into the hex number 0x05B0? We’ll use the same technique we used before, but because we’re looking for digits, we’ll divide by 16 instead of 256:

1456 / 16 = 91, remainder 0
  91 / 16 =  5, remainder 11
   5 / 16 =  0, remainder 5
   0 / 16 =  0, remainder 0

Looking at the remainders and working our way from the bottom up, we have 0, 5, 11, and 0. The hex value for 11 is B, so we construct the hex number 05B0.

But what about the 0x in front? That’s just a marker to state this is a hex number, not decimal or binary. Note that there are lots of ways to denote hex numbers, but this blog will stick with 0x. For binary numbers, this blog will use 0b in front as well. This is necessary because the number 101 is valid in hex, decimal, and binary, although it represents three different values in each.

It’s important to note that these different number systems only change the way you write numbers, not what they mean. They don’t change the actual number. It doesn’t matter if you say you have 0b1011 jelly beans or 11 jelly beans or 0x0B jelly beans, you still have the same number of jelly beans.

So why use hex at all?

One Special Relationship

Binary is the language of computers, and representing binary numbers is easily and compactly done using hexadecimal. Converting between the two can be trivially easy, making it extremely useful for programmers.

Let’s explore this a little. Recall that the largest number you can store in one byte of memory is 255. In binary, this is 0b11111111. In hex, this is represented as 0xFF:

255 / 16 = 15, remainder 15 (0xF)
 15 / 16 =  0, remainder 15 (0xF)

If you look at 0xF in the chart above, you’ll see it corresponds to the binary 0b1111. Since 0xFF is the same as 0b1111 1111, you can either convert between binary and hex by dividing (boring), or by simply splitting the binary number into groups of four digits and looking each up in the table above.

Remember we said earlier that you can store a number as big as 65,535 in two bytes of memory. That is 0b1111 1111 1111 1111. What do you think that number looks like in hex? Try it first, then take a look below.

No matter which method you use, either long division and remainders, or simply converting groups of four binary digits into single hex digits, you should get the answer 0xFFFF.

Here are some more examples. Feel free to check these out for yourself:

0b1001 1011 = 0x9B
0b0000 0011 = 0x03
0b1101 1110 1010 1101 1011 1110 1110 1111 = 0xDEADBEEF

That last one is a magic debugging number used by a number of systems to mark freed kernel memory which should not be used by drivers.

There’s one last thing to mention when using binary and hex numbers. This blog will always provide leading zeros when writing hex and binary numbers. For example, I wrote 0x05B0 and 0x03 above, not 0x5B0 and 0x3. You may see either in your day to day coding exploration, however.

So How Do I Use This?

The close relationship between binary and hex makes it a crucial tool in understanding low-level computer code. While you may not use hex in your daily coding experience at first, knowing it exists and understanding it may help you clarify any limitations you may see.

One place you may see hex in your daily life is when your computer crashes. If you’ve ever seen a Blue Screen of Death in Windows, or a kernel panic on Mac or Unix system, you may have seen a lot of wierd looking text on the screen:

Kernel Panic. Not at the disco.

While the information may still be a mystery, at least you now know you’re looking at numbers. In fact, you may be able to deduce that a lot of those numbers are actually addresses of memory locations, and you would be right.

We’ll dip more into hex and the special relationship between it and binary later in this blog. For now, knowing hex is there, that it’s just another way to write numbers, and it’s closely tied to binary will be enough.

Next week, we’ll expand our discussion of storing text in memory by talking about how a computer program knows what kind of data is stored where.

UPDATED: 01.Jul 2020, changed 0xFFFFFFFF to 0XFFFF, updated formatting.