One of the very first things that you should learn if you are dealing with programming of any variety is the concept of binary and hexadecimal number systems. The foundation of computers is based in binary -- 1s and 0s -- and it's cousin hexadecimal. Everything from HTML/CSS color codes to URL encoding to IP addresses to memory/hard drive capacity and everything in between exposes the concept of binary and hexadecimal With a basic understanding, working with computers is a bit easier.

We all use the decimal -- base 10 -- number system. We count from 0 to 9, then begin over with 10 when we run of of digits. There are nine digits plus zero in our system of counting, and everyone knows how to do basic arithmetic with base 10 numbers. The numbers are actually *symbols* representing digits in the decimal system. Different number systems have different sets of symbols used to count.

Computers don't understand concepts as complex as that. They understand 0s and 1s -- binary, or base 2. A binary number can be considered as "on" (1) or "off" (0). These binary digits (also called "bits") can be grouped for easier use by humans, and for easier transportation through the computer. You say a bit is "set" when the value is 1.

Early personal computers used 8-bit processors -- 8 of these binary digits could be moved simultaneously. Newer computers use 32-bit or 64-bit processors. These processors can move data much more quickly.

In binary, you count from 0 to 1, then begin over with 10 because you ran out of digits. This is not "ten", but "one-zero", or decimal equivalent to "2". To count from 0 to 15 in binary, you would count like this:

Dec Binary

0 0000

1 0001

2 0010

3 0011

4 0100

5 0101

6 0110

7 0111

8 1000

9 1001

10 1010

11 1011

12 1100

13 1101

14 1110

15 1111

As you can see, you can store numbers from 0 to 15 (16 different values) in 4 bits. In decimal, each digit from *right to left* represents one power of ten: first digit is 10^{0} or 1; second digit is 10^{1}, or 10; third digit is 10^{2} (10*10), or 100; fourth digit is 10^{3} (10*10*10), or 1,000; fifth digit is 10^{4} (10*10*10*10), or 10,000; and so on. In binary, this works the same way: each digit from right to left represents one power of two: first digit is 2^{0} or 1; second digit is 2^{1}, or 2; third digit is 2^{2} (2*2), or 4; fourth digit is 2^{3} (2*2*2), or 8; fifth digit is 2^{4} (2*2*2*2), or 16; and so on.

Note: Any number raised to the power of 0 is 1. Any number raised to the power of 1 is the number itself.

We have a shorthand way of describing 4 bits of data -- hexadecimal notation. The hexadecimal -- base 16 -- number system uses symbols 0-9 and A-F as its digits. This gives us 16 separate digits. We count in hexadecimal from 0 to F and then begin over with 10. This is not "ten", but "one-zero", or decimal equivalent to "16". To count from 0 to 15 in hexadecimal, you would count like this (with the decimal and binary equivalents listed):

Dec Binary Hex

0 0000 0

1 0001 1

2 0010 2

3 0011 3

4 0100 4

5 0101 5

6 0110 6

7 0111 7

8 1000 8

9 1001 9

10 1010 A

11 1011 B

12 1100 C

13 1101 D

14 1110 E

15 1111 F

You can see that the hexadecimal numbers correspond to the binary and decimal numbers shown. In hexadecimal, each digit from *right to left* represents one power of sixteen: first digit is 16^{0} or 1; second digit is 16^{1}, or 16; third digit is 16^{2} (16*16), or 256; fourth digit is 16^{3} (16*16*16), or 4,096; fifth digit is 16^{4} (16*16*16*16), or 65,536; and so on. You can store values from 0 to 65,535 using 4 hexadecimal digits.

When you group together 8 bits, it is also known as a byte. Here is a sampling of a few different numbers from 0 to 255:

Dec Binary Hex

1 0000 0001 01

...

16 0001 0000 10

...

32 0010 0000 20

...

64 0100 0000 40

...

128
1000 0000 80

...

170
1010 1010 AA

...

255 1111 1111 FF

As you can see, the bigger the numbers get, the harder it is to figure out the binary number equivalent unless you know the trick -- each group of 4 corresponds to a hexadecimal digit, and each group of 4 counts from 0 to 15 in the same way. Knowing that, you can translate any binary number into hex, or into the decimal equivalent:

1010101010010010

First, break it into groups of 4:

1010 1010 1001 0010

Then translate the numbers into hex and decimal:

AA 92 or 170, 146

Then multiply the decimal digits by the appropriate power of 16:

146*16^{0} = 146* 1 = 146

170*16^{2} = 170*256 = 43,520

-------------------------------

43,666

Binary and Hexadecimal numbers can be used in basic math operations just like decimal numbers. In decimal, to do addition you might create a problem like this:

1,039

+ 238

------

1,277

Going through the steps, you add the least significant digit first (the right-most digit). If you come up with a number greater than the number of digits (anything over 9), you carry a 1 to the next column. To add the numbers in the second least significant position (2nd from the right) you would add the 3 plus the 3 and add the 1 you carried over. This is simple and the same concept holds true for binary and hexadecimal:

0100 0000 1111

+ 1110 1110

-----------------

0100 1111 1101

Just as in the decimal example, you add from right to left. The least significant column gives you 1 + 0 = 1. Bring that down. The next column gives you 1 + 1 = 10. Put down the zero and carry the 1 to the next column. In the third column we are adding 1 + 1 + the carryover 1 = 11. Put down the 1 and carry over the one again. And continue to the end.

Hex works exactly the same way:

040F

+ EE

----

04FD

Just as in the decimal example, you add right to left. The least significant column gives you F + E = 1. F is 15, E is 14, giving you 29, or 1D. Bring down the D and carry over the 1. The next column gives you 0 + E + 1 that you carried over = F. Put that down in the answer. In the third column we are simply bringing down the 4.

All three of these examples are equivalent (1,039 + 238 = 1,277).

The basic Windows calculator can be used to convert and calculate hex, binary, decimal, and octal numbers if you choose the Scientific calculator from the View menu, as shown in Figure 1:

**Figure 1: The Windows calculator can be used for binary/hex conversion and math**

Now that you have a basic knowledge of binary and hexadecimal, how can you use it? Here are a few common applications of the concepts:

**ASCII:** ASCII is a character system developed in the early days of computers as a representation of Western characters that can be stored in 7 bits (0 to 127) of a byte. The 8th bit was frequently used as an error checking bit. The first 32 characters (0 to 31, or 0000 0000 to 0001 1111 in binary) are control characters. ASCII capital letters go from 65 to 90 (binary 0100 0001 to 0101 1010) and small letters go from 97 to 122 (binary 0110 0001 to 0111 1010). The difference between a capital letter and a small letter is exactly 32 -- you can see from the binary representations that 6th bit from the right is set in small letters, and not set in capital letters. Check http://www.asciitable.com/ for a table of codes.

**URL Encoding:** URL encoding of a character is something you see frequently in web programming, on URLs and other places. When you see a URL encoded set of characters, the actual values are ASCII hexadecimal representations with a preceding % to indicate that it is a URL encoded value. Some typical examples are %20 (ASCII 32, or space), %2E (ASCII 46, or a period), and %25 (ASCII 37, or a percent sign).

**UTF-8:** The most popular UNICODE variety can store many more values than ASCII, because it is a 4 byte system. The first byte contains the equivalent of the ASCII characters (Unicode range U+0000 to U+007F). The second byte is needed for Latin letters and for characters from Greek, Cyrillic, Armenian, Hebrew, Arabic, Syriac and Thaana alphabets (Unicode range U+0080 to U+07FF).

**HTML Character Codes:** These are special ”characters in HTML that can be represented in Decimal or Hexadecimal. For example, curly quotes (left and right) can be represented using **“** and** ”** in decimal format, or **“** and** ” **in hexadecimal format.

**Color Codes:** Color codes are frequently written as #FFFFFF, #FF0000, #00FF00, etc. Colors can be broken down using this code to their red, green, and blue counterparts: #FF FF FF, would be red (255), green (255), and blue (255). As you know, when all colors are on full, you get pure white. When all colors are off (#00 00 00) you get pure black. When one value is full on and the rest are off, you get the purest form of that color: #FF 00 00 would be pure red and #00 00 FF would be pure blue. When all three values (R, G, B) are the same, you get shades of gray (#F0F0F0, #CCCCCC, #3E3E3E).

**Data Storage:** Frequently data is stored within a fixed number of bytes. For example, integers that can be stored in 2 bytes would represent numbers from 0 to 65535. In some systems, the left-most bit (most significant bit) is used to denote positive or negative -- if the bit is set, the number is negative. Integer values can go from -32,768 to 32767. If the number is stored in 4 bytes instead of 2, the values you are able to store go from 0 to 4,294,967,295, or if the most significant bit is used to denote positive or negative, values from -2,147,483,648 to 2,147,483,647.

**Computer Memory:** Memory is often thought of in bytes, kilobytes, megabytes, and gigabytes, but technically computer memory stores bits -- simple 1/0, yes/no answers. A kilobyte is 1024 bytes (not 1000) or 8192 bits, a megabyte is 1,048,576 bytes or 8,388,608 bits, and a gigabyte is 1,073,741,824 bytes or 8,589,934,592 bits. If you are storing ASCII characters, a full page of text is approximately 500 words or 2500 characters (about 2.5K.)

**Networking:** Hexadecimal notation is used frequently in networking, such as IP addresses and subnet masks. A subnet mask is essentially a binary number used to mask certain binary digits from the IP address to identify the subnetwork and host addresses on the network. Take the subnet mask of 255.255.255.240 as an example, or in hex as FF FF FF F0, or in binary as 1111 1111 1111 1100 -- the last two bits represent the available host addresses.

Binary and Hexadecimal math is certainly a dry topic, but key to understanding computers in general, and countless aspects of computer programming, design, and networking.