Wednesday, May 18, 2011

How to Count in Binary, Octal, and Hexadecimal

Programming has something to do with Math and Logic. I think it is valuable for a beginning programmer to have a reference to the type of math which makes computers work... So, here it is:

Counting Like a Programmer

Since computers are all composed of electrical signals and switching mechanisms which are either turned on or off, the computer works in "1's and 0's." Basically, the 1 means electricity is flowing in a particular bit of memory, and the 0 means it is absent.

Humans have ten fingers, so we developed a base-10 system where we have the digits 0 through 9 to represent our basic type of counting. When we run out of symbols (get to 9) we solve the problem by adding a new place, the "tens place" and then starting over with a zero in the one's place, in other words, after 9 we find the number "10" (ten) which occupies two digits.

In the computer, only the digits 0 and 1 really exist on the electrical level, so it counts from 0 to 1, then it runs out of symbols and has to add a new place. But in this case, it is the "twos place", and counting starts over with a zero in the one's place. So after the number 1 in binary comes 10. Binary is also called base-2. When we are counting in other bases besides decimal, we don't say things like "ten" and "seventeen", because those are exact decimal amounts, instead when we look at the binary number 10 we speak it out loud by saying "one zero" or even "two" (actually saying two is converting it back to decimal for the purpose of speaking its meaning aloud.)

In Decimal, the place values are one's place, ten's place, hundred's place, thousand's place, etc. And in binary they are the one's place, two's place, four's place, eight's place, sixteen's place, thirty-two's place, sixty-four's place, and one hundred twenty eight's place, etc. In other words, each digit has double the place value of the digit to its right. These are the "powers of two" and you will see this series of numbers often in computing. I've been programming for about 18 years and I can give this much of the sequence easily off the top of my head: 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, 4096, 8192, 16384, 32768, 65536, etc. You don't need to try to memorize that sequence, but knowing the first few powers of two may be helpful.

Counting in Binary compared to Decimal, Hexadecimal, and Octal:
Binary Decimal Hexadecimal Octal
0000 0 0 0
0001 1 1 1
0010 2 2 2
0011 3 3 3
0100 4 4 4
0101 5 5 5
0110 6 6 6
0111 7 7 7
1000 8 8 10
1001 9 9 11
1010 10 A 12
1011 11 B 13
1100 12 C 14
1101 13 D 15
1110 14 E 16
1111 15 F 17
10000 16 10 20

(In the above table, I prefixed the binary numbers with zero to pad them out to four digits in length merely as custom. As with decimal numbers, leading zeros are unimportant to meaning.)

Binary takes a lot of writing if you wish to record large numbers, so computer programmers have used certain types of shorthand to make the representation of binary easier to deal with. Converting to decimal would be one way to handle it, but it is not very easy to convert between binary and decimal in your head, so instead programmers have made use of the Hexadecimal (base-16) and Octal (base-8) systems, which I will now explain:

You will observe in the chart above that every four digit binary number corresponds exactly to one hexadecimal digit. Hexadecimal is a system using the digits 0 through 9 and A through F, a total of sixteen possible values (zero through fifteen) instead of only using 0 through 9 like the decimal system does. In Hexadecimal, when you have counted all the way up to F, you have to put a 1 into the sixteen's place, and then start over with zero in the one's place, giving you the hexadecimal number "10" (one zero, or sixteen.) Because of this, you can convert a long binary number into Hexadecimal just by breaking it into groups of four starting on the right (least significant) side of the number, and then switching to the appropriate hex digit. Example:

I want to convert this number: 101101010100010110101110100101

So first I break it into groups of four, starting on the right. You'll notice there are a couple of extra digits left over on the left side:

10 1101 0101 0001 0110 1011 1010 0101

Now I convert each group of four into its corresponding hex digit. Starting from the right, 0101 becomes 5, then 1010 becomes A, 1011 becomes B, 0110 becomes 6, 0001 becomes 1, 0101 becomes 5, 1101 becomes D, and we pad the leftover digits with zeros on the left, so 10 is considered as 0010 and it becomes 2:

00101101010100010110101110100101
2D516BA5

So the resulting hex number is: 2D516BA5.

Like that.. Easy, huh?

Convert back is done the same way. Just take each hex digit, and translate it back into the four corresponding binary digits.

Converting to and from octal works the same way except that each octal digit corresponds with a group of three binary digits instead of four. People don't use octal very much today in programming, but it is used in the numeric file permissions on Linux and Unix based computers, so you will see it from time to time.

Something odd about me...

So, I have developed a habit of counting in binary using my fingers in the following way. I have assigned each finger a place value, and to represent a certain number I press those fingers against the table top. I leave the other fingers lifted. I have practiced counting this way with my fingers and I can count from zero to fifteen in binary in less than two seconds.

If most people were going to try to do this, they would probably assign the place values to the fingers in order, but since I was a trumpet player, I let the middle, index, and ring fingers be assigned the first three places, that way the first part of the sequence is the same as a descending chromatic scale on a trumpet. So, I assign my fingers values like this: middle finger = one's place, index finger = two's place, ring finger = four's place, pinky = eight's place, thumb = sixteen's place. But, that's just me and my weird habit. You don't need to learn to drum out binary on the table top if you don't want to!

Converting from Binary to Decimal and Back

So, there is one last thing. The nasty part of this lesson. How to convert between Binary and Decimal. To go from Binary to Decimal is pretty easy, just look at all the digits with a "1" in them, and add up the place values of those digits. For example:

10011

There is a 1 in the one's place, the two's place, and the sixteen's place, so we add those together: 16 + 2 + 1 and get 19. The decimal equivalent of this number is 19.

To convert the other direction is harder, but only because we have to subtract. Start with the decimal number, in this case, we will use 21. Start with a binary number of all zeros, then find the biggest place value that is smaller than this number, subtract the place value from the number, and mark a 1 in its place. In this case, 16 is the number, so we take 21 - 16 and get 5, putting a 1 in the sixteen's place. Now we repeat the process, the biggest number we can subtract is 4, so we take 5 - 4 and get 1, putting a 1 in the four's place. Now we have 1 left, 1 - 1 = 0 so we put a 1 in the 1's place.

The binary is therefore: 10101.

Try this a few times. If you need to, you can check your work by using the Calculator program on your computer when it is set to Programming mode. Make sure the base is set to the base you are converting from, then enter the number and flip to the base you want to see the same number represented in.

Wrapping it Up

I know this lesson was a little dry. I mean, who wants to do a bunch of Math, right? But it is an important subject which will help you a lot later on. The next few posts should be a lot more fun.

Next Post: Binary Logic.

No comments:

Post a Comment