Thanks to OSNews.com for pointing out this site aimed at teaching C. While the site is still too new and the number of articles there are too few in number to really indicate if the authors efforts are worthwhile, but I enjoyed reading the articles and I feel he is heading in the right direction. However, whenever I come across a programming tutorial, I always find one thing glaringly omitted when talking about hexadecimal numbers. So much time is spent on how to work with them, but very rarely does anyone ever say why. And I find that strange. Its almost like your just expected to accept it, without any real knowledge as to why your working with a number system that is not the same as the number system that was crammed down your throat almost all your life.
The main reason why we use hexadecimal numbers is because it is much easier to express binary number representations in hex than it is in any other base number system. Computers do not actually work in hex (don’t laugh, beginning students do ask that question). Lets look at an example, using a byte. Bytes are typically 8 bits, and can store the values 0 – 255 (0000 0000 – 1111 1111 in binary). For people, expressing numbers in binary is not convenient. I am not going to turn around to my co-worker and tell him that my phone number is 101 101 101 001 010 001 010 for obvious reasons. Imaging having to try and work with that on a daily basis. So a more convenient expression is needed for the human side.
Since a byte is 8 bits, it makes sense to divide that up into two groups, the top 4 bits and the low 4 bits. Since 4 bits gives you the possible range from 0 – 15, a base 16 system is easier to work with, especially if you are only familiar with alphanumeric characters (I don’t know of any languages have 255 letters in their alphabet, but I am naive and not worldly). It’s easier to express a binary value to another person as “A” then it is to express it as “1010”. This way I can simple use 2 hex values to represent a byte and have it work cleanly. This way if I am piss poor at math, I only need to memorize the multiplication tables up to 15. So if I have a hex value of CE, I can easily determine that 12 * 14 = 206 in decimal, and can easily write it out in binary as 1100 1110. Trying to convert from binary would require me to know what each place holder represents, and add all the values together (128 + 64 + 8 + 4 + 2 = 206). It’s much easier to work with binary through hex than any other base system. Further reading available here.
Octal comes into a close second. In octal, you can represent, at most, 3 bits with a single octal digit. So its very easy to say 311 is 11 001 001. The problem with octal, as you can see, is that the 3rd octal digit can only goes as high as 3, so it does not represent a byte as cleanly as hex. Octal is used in Unix for permissions due to its 3-bit nature. If we take the three specific entitlements (read, write, execute) for a file, we find that it coincides very well with octal. That’s why you see those really funky “chmod 744” commands, because they are octal representation of permissions, 111 100 100, or R-W-E, Read, Read for owner, group, world respectively (at least that is how it was explained to me). The leftmost bit represents the read flag, the middle one represents the write flag, and the rightmost flag represents execute. So if you wanted the permission for read-write, it would be 110, or 6. Read and execute would be 101 or 5.
Incidentally, there is such a thing as a binary coded decimal. Binary coded decimals are used more for our convenience than for the machines. I have seen BCD more often in electronic circuits using 7 segment displays, and various encoding methods used in PC’s. In BCD, 4 bit patterns are used to represent one base 10 digit. Once the value 9 is represented, another 4 bits are allocated. To compare, the value 10 in straight binary is 1010, where as in BCD it is 0001 0000. Another example is in straight binary, 29 is represented as 0001 1101. In BCD it is 0010 1001.