Computer Numbers: Binary & Hexadecimal
Last time, I talked about numbering systems and especially how the base numbering system works. We already know the decimal system best of all, because we use it every day. However, the computer is not fond of this system. It rather uses the binary systems for its numeric representations. But what has the hexadecimal systems to do with this?
Binary
Let’s start with the binary system, which modern computer systems use nowadays. Binary is a base-2 numeric system. Thus, it uses the power of two and has two unique symbols to represent numbers in binary: 0 and 1. You might have worked with the binary system before while programming or studying computer science.
However, you might say, is there any use to learn about binary? The computer can convert it, right? Well, yes, the computer can convert binary to decimal and the other way around. When writing an algorithm, you want it to be as fast as possible and as optimised as possible. Using the decimal system in an algorithm would make it considerably slower because the CPU has to convert the decimal numbers every time. Thus, it is good to have a thorough understanding about the binary numeric system.
Converting binary to decimal is rather easy. You take the binary number and multiply each digit with two to the power of the digit’s position. So, if we want to convert 01100100 to a decimal representation, we get the following:
0 x 2^8 + 1 x 2^7 + 1 x 2^6 + 0 x 2^5 + 0 x 2^4 + 1 x 2^3 + 0 x 2^2 + 0 x 2^1
0 + 64 + 32 + 0 + 0 + 4 + 0 + 0
100
From decimal to binary is also relatively simple. To do that, you follow these steps:
- Check whether the number is even or not. If it is even, the first number is a zero, otherwise it’s a one;
- Divide the number by two and throw away any fractional remainder;
- If the quotient is zero, the algorithm is complete;
- If the quotient is not zero and the number is odd, prefix the number with a 1, otherwise prefix the number with a 0;
- Repeat the algorithm until it is complete.
Sometimes, you need to work with big numbers. For instance, say we have a variable with the decimal value 1234567. In binary, this number is 100101101011010000111. Not very readable, is it? In order to make these big values more readable in binary, you can add underscores after every group of four bits. So in this case, you would get 0001_0010_1101_0110_1000_0111. To increase the readability, I also added zeroes at the beginning to create a group of four. Adding zeroes has no effect on the value of the number after all. Another way to ensure that you are working with binary values, is to add prefixes or suffixes to a binary number. The table below shows how a few common languages define their binaries:
Language (Family) | Prefix/Suffix |
C, C++, C#, Java (and derivatives) | 0b01100100 |
MASM (Microsoft Assembly) | 01100100b or 01100100B |
Visual Basic (VB) | &B01100100 or &b01100100 |
Pascal (and derivatives) | %01100100 |
HLA (High Level Assembly) | %01100100 |
Hexadecimal
Computers love the binary numeric system, however it is still a bit chunky. Programmers prefer the hexadecimal numeric system for two main reasons (and a third side reason):
- It is very compact;
- Easy to convert into binary;
- Less awkward than binary.
Because it is very compact, the readability of programs is increased by using hexadecimal notation instead of binary. But why is it so easy to convert hexadecimal to binary?
Well, let’s start by seeing what the hexadecimal numeric system is. It is another base-n numeric system. In this case, it is a base-16 system. It uses the power of 16 for each successive value and it uses the symbols 0 to 9 and A to F. This means that it is possible that certain words are actually a number. For example, BEEF can either mean the meat of a cow or it is the number 48879 in hexadecimal notation.
So, how do you distinguish in a program that BEEF is just a variable name or a hexadecimal value? Programming languages have their own prefix or suffix to indicate a hexadecimal value. Below is a table with the most popular ones:
Language (Family) | Prefix/Suffix |
C, C++, C#, Java (and derivatives) | 0xBEEF |
MASM (Microsoft Assembly) | 0BEEFH or 0BEEFh |
Visual Basic (VB) | &HBEEF or &hBEEF |
Pascal (and derivatives) | $BEEF |
HLA (High Level Assembly) | $BEEF |
It has been established that the hexadecimal notation is compact but it was also easy to convert to binary and back. How does that work? As I said earlier, to make binary numbers more readable, we group them into four bits and separate them with underscores. We do this for one simple reason: four bits have a maximum value of 15. The maximum value of one hexadecimal digit is 15. Do you see it already? Each group of four bits can be converted to one digit in the hexadecimal notation! Below is a handy table for this conversion:
Binary | Hexadecimal |
0000 | 0 |
0001 | 1 |
0010 | 2 |
0011 | 3 |
0100 | 4 |
0101 | 5 |
0110 | 6 |
0111 | 7 |
1000 | 8 |
1001 | 9 |
1010 | A |
1011 | B |
1100 | C |
1101 | D |
1110 | E |
1111 | F |
With this, you easily convert any binary value to hexadecimal and the other way around. Let me show you!
Binary | 1001 | 1110 | 0010 | 0110 |
Hexadecimal | 9 | E | 2 | 6 |
This shows the correlation between the binary system preffered by computers and the hexadecimal system used by many programmers. Using these native values, the CPU doesn’t have to convert from and to the decimal system which will increase the performance in the long run.