Computer Numbering Systems
Binary, Decimal, and Hexadecimal

The DECIMAL Numbering System ( BASE10 )

Numbering systems are based off of something familiar like the number of fingers you have or repeating patterns such as the Earth orbiting the Sun (hours : minutes : secs, days, months, and years). By far the most common numbering system in use today is the Decimal system which is based on the 10 numbers 0 through 9.  Let's cover the Decimal system quickly as a refresher from grammar school.

Each place a number holds has a value based on the power of 10 in the decimal number system. This is why the decimal system is referred to as a BASE10 numbering system because of the relation of each digit to the left being 10 times more in value to the digit on the right. In grammar school you learned these places were called the 1's place, the 10's place, the 100's place, and so on. For example the decimal number 94,384 breaks down as follows:

|-------------------------------------------------------|
|              The Decimal Numbering System             |
|-------------------------------------------------------|
| Place ->  10,000's  1000's    100's    10's      1's  | = 9x10000 + 4x1000 + 3x100 + 8x10 + 4x1
|----------|--------|--------|--------|--------|--------|
| Value -> |    9   |    4   |    3   |    8   |    4   | = 90,000  + 4,000  +  300  +  80  +  4
|----------|--------|--------|--------|--------|--------|
| Power ->     104       103      102      101       100  | =  9x104  +  4x103  + 3x102 + 8x101 + 4x100
|-------------------------------------------------------|
|      Powers and places continue left to infinity      |
|-------------------------------------------------------|

When we count up using the decimal system numbers to the left need to increase by 1 when the value of 9 is exceeded. For example:

 0...1...2...3...4...5...6...7...8...9..the 1's place will reset to 0 and 1 will be added to the 10's place:
10..11..12..13..14..15..16..17..18..19..the 1's place will reset to 0 and 1 will be added to the 10's place:
20..21.. and on and on until ...
90..91..92..93..94..95..96..97..98..99..the 1's place will reset to 0 and 1 will be added to the 10's place which forces the 10's place to reset to 0 and 1 will be added to the 100's place:
100.101.102.103.. you get the idea, the same way an odometer ticks up in a car.

This cycle happens because each digit in the decimal system is based on 10 numbers available, 0 through 9.

It's important to note that the value of zero ( 0 ) is considered a number which is the beginning of the 10 number sequence for decimal: 0 through 9. For any given number system the subscript value in BASE, for example BASE10 , identifies the numbers used from 0 to that subscript number - 1, or 9 in decimal's case. Therefore, a BASE4 numbering system would include the numbers of 0 through 3. Zero ( 0 ) is always the starting point.

The BINARY Numbering System ( BASE2 )

There is a problem however with the decimal numbering system ... computers can count with it. Yes, yes, software written for computers has no problem counting in any BASE you desire (and we'll get to why this is possible later), but at the heart of any computer only two things are known: On and Off.

Computers are based on electronic circuits that allow electrons to flow. This electron flow is known as electricity or voltage. There are two major types of electronic circuits available, analog and digital. An analog electronic circuit is used for electrical signals that are constantly changing such as the radio waves transmitted from a radio station. An analog electrical signal, such as a radio wave, can carry an infinite amount of information within it. Take a one second radio wave and zoom in on half of it. Now, take that half and zoom in on half of it ... now zoom in on half of that, and then half of that, half of that, etc.. You can keep doing this to infinity. Design an analog circuit well enough and you could, theoretically, transmit the entire Encyclopedia Britannica in just a one or two second radio wave burst. So what's the problem? Well, analog circuits are constantly changing, noisy, and prone to errors which is something that a computer can't tolerate.

Digital electronic circuits on the other hand deal in absolutes. Like a light switch turning on a light bulb the circuit is either "on" or it is "off". There's no infinite drilling down that can be done with a digital signal. On will always be on, and off with always be off. This eliminates the problem of noise. Reach a certain electrical voltage level, say 5 volts, and the circuit is on, any other voltage below this level indicates that the circuit is off. Design a digital circuit well enough and you could, theoretically, transmit the entire Encyclopedia Britannica in a second or two. The exciting thing is digital circuits are not quite there yet but they will be very soon, and eventually surpass this.

So, why are digital circuits preferred? The "on" and "off" behavior can be translated into something tangible, a number system. Just like humans have 10 fingers and therefore use this as the basis for decimal, computers have two "fingers" or states and use this as the basis for the binary number system. "On" equates to a one ( 1 ) and "off" equates to a zero ( 0 ). The computer has all it needs to count in the binary, or BASE2 numbering system.

Each place a number holds has a value based on the power of 2 in the binary number system. This is why the binary system is referred to as a BASE2 numbering system because of the relation of each digit to the left being 2 times more in value to the digit on the right. For example, the binary number 10110101 breaks down as follows:

|----------------------------------------------------------|
|               The Binary Numbering System                |
|----------------------------------------------------------|
| Place ->  128's  64's  32's  16's  8's   4's   2's   1's | =1x128+0x64+1x32+1x16+0x8+1x4+0x2+1x1
|----------|-----|-----|-----|-----|-----|-----|-----|-----|
| Value -> |  1  |  0  |  1  |  1  |  0  |  1  |  0  |  1  | = 1280 + 32 + 16 + 0 + 4 + 0 + 1
|----------|-----|-----|-----|-----|-----|-----|-----|-----|
| Power -> |  27    26     25    24    23     22    21    20  | = 1x27+0x26+1x25+1x24+0x23+1x22+0x21+1x20
|----------------------------------------------------------|
|       Powers and places continue left to infinity        |   128+0+32+16+0+4+0+1 = 181 in decimal
|----------------------------------------------------------|

Binary is structured the same way as decimal. The only difference is that each number place is based on a power 2 instead of a power of 10. This makes converting binary to decimal uniquely easy. Simply add all the place holder values together wherever a one ( 1 ) appears as the chart above shows. Now that the computer has a number system that it can count in software can be written to convert the binary numbers stored in the computer to any other BASE number system desired.

Counting up in the binary system is no different from the decimal system except this time numbers to the left increase by 1 when the value of 1 is exceeded. For example:

0..1 the 1's place will rest to 0 and 1 will be added to the 2's place:
10..11 the 1's place will reset to 0, 1 will be added to the 2's place which forces the 2's place to reset to 0 and 1 will be added to the 4's place:
100..101..110..111 the 1's place will reset to 0, 1 will be added to the 2's place which forces the 2's place to rest to 0, 1 will be added to the 4's place which forces the 4's place to reset to 0 and 1 will be added to the 8's place:
1000..1001..1010..1011..1100..1101..1110..1111 and so on.

Binary counts up exactly the same as decimal albeit much quicker because of binary only having two numerals to deal with. There is a chart down in the hexadecimal section that shows the transition vertically which may help to visualize the pattern.

Groups of binary numbers also have unique names identifying their bit length:

|------------------------------------------------------------------------------------------------|
|    Name     | Bits |           Value Range           |                  Notes                  |
|-------------|------|---------------------------------|-----------------------------------------|
| Bit         |   1  | 0 to 1                          | Useful as an on/off or true/false flag  |
| Crumb       |   2  | 0 to 3                          | Useful when 4bit computers were used    |
| Nibble      |   4  | 0 to 15                         | One hexadecimal value (see below)       |
| Byte        |   8  | 0 to 255                        | One character such as "A" or "B"        |
| Word        |  16  | 0 to 65,535                     | 64 Kilobytes (8/16bit computer max RAM) |
| Double Word |  32  | 0 to 4,294,967,295              |  4 Gigabytes (  32bit computer max RAM) |
| Quad Word   |  64  | 0 to 18,446,744,073,709,551,615 | 18 Exabytes  (  64bit computer max RAM) |
|------------------------------------------------------------------------------------------------|

The HEXADECIMAL Numbering System ( BASE16 )

The hexadecimal numbering system is used by programmers as a short-hand version of the binary numbering system. The hexadecimal numbering system uses 16 numerals from 0 to 9 and then A through F. Since decimal does not offer 16 unique numbers the letters A through F need to be used to represent the values of 10 through 15. Each place a number holds has a value based on the power of 16 in the hexadecimal number system. This is why the hexadecimal system is referred to as a BASE16 numbering system because of the relation of each digit to the left being 16 times more in value to the digit on the right. For example, the hexadecimal number F3B6 breaks down as follows:

|----------------------------------------------|
|       The Hexadecimal Numbering System       |
|----------------------------------------------|
| Place ->   4096's    256's    16's      1's  | = Fx4096 + 3x256 + Bx16  + 6x1  (F = 15, B = 11)
|----------|--------|--------|--------|--------|
| Value -> |    F   |    3   |    B   |    6   | = 61,440768  +  176  +  6
|----------|--------|--------|--------|--------|
| Power ->     163       162      161       160  | = Fx163  +  3x162 + Bx161 + 6x160
|----------------------------------------------|
| Powers and places continue left to infinity  |   61,440768  +  176  + 6 = 62,390 in decimal
|----------------------------------------------|

Hexadecimal is structured the same way as decimal and binary. The only difference is that each number place is based on a power 16 instead of a power of 10 or 2. Hexadecimal is very easily converted to binary. Even a number like F3B6 I can do in my head --> 1111001110110110. I really did do that from memory as I typed the binary number in, but how?

The chart below will help to shed some light on the magic of converting such a strange hexadecimal number to binary on the fly:

|--------------------------------|
|        Conversion Chart        |           Converting the hex number F3B6 to binary
|--------------------------------|          ------------------------------------------
| Decimal | Binary | Hexadecimal |     Each hexadecimal digit represents a binary nibble as
|---------|--------|-------------|     seen in the chart.
|    0    |  0000  |      0      |
|    1    |  0001  |      1      |     F represents 1111
|    2    |  0010  |      2      |     3 represents 0011
|    3    |  0011  |      3      |     B represents 1011
|    4    |  0100  |      4      |     6 represents 0110
|    5    |  0101  |      5      |
|    6    |  0110  |      6      |     Now simply piece them all together:
|    7    |  0111  |      7      |
|    8    |  1000  |      8      |      F    3    B    6
|    9    |  1001  |      9      |     1111 0011 1011 0110 = 1111001110110110 in binary
|   10    |  1010  |      A      |
|   11    |  1011  |      B      |     Programmers needed a way to represent binary numbers
|   12    |  1100  |      C      |     in a smaller more compact fashion. Using hexadecimal
|   13    |  1101  |      D      |     was the answer to this.
|   14    |  1110  |      E      |
|   15    |  1111  |      F      |     Recalling this chart from your memory becomes second
|--------------------------------|     nature the more that you use hexadecimal numbers.

Back in the very early days of programming, we're talking pre-1980's, computers had barely reached the 16 bit level. What 16 bit actually means is the number of data paths, or address lines, that a CPU can access. In a 16 bit computer there are 65,536 addresses ( 215 = 0 to 65,535) , or memory locations, accessible to the CPU by loading the 16 address lines with any 16 bit binary number.

For example, let's say the address for the printer port in one of those old computers is 240 in decimal. If you convert 240 to a 16 bit binary number you get 0000000011110000. Now, take a nibble of bits at a time starting from the right and working left and you get:

0000 = 0
1111 = F
0000 = 0
0000 = 0

That binary number converts to 00F0 in hexadecimal (simply use the chart above). So the programmer would put this into their assembler (assembly language or machine code) and that hexadecimal number would activate the relevant address lines on the address bus. Wherever a one ( 1 ) is seen that address line would get turned "on" or 5 volts applied to it. The computer now knows that the next piece of information given to it needs to be sent to the printer port located at 240 or F0 (the leading 0's can be dropped). Using hexadecimal as short-hand for binary made coding easier for those early programmers. Before hexadecimal was used programmers actually programmed the 1's and 0's in! Imagine writing code today using only 1's and 0's. It can be done but why torture yourself?

Today modern languages such as QB64 do the heavy lifting for us. That 240 is converted to hexadecimal and/or binary behind the scenes for us by the compiler so today's programmer can focus on the code instead of the conversions.

Hexadecimal, and even binary, numbers are still used in programming all the time. In QB64 if you wish to express a hexadecimal value you precede it with &H:

PrinterPort% = &HF0 ' printer port 240

and binary numbers are preceded with a &B:

PrinterPort% = &B11110000 ' printer port 240

Colors on web sites that offer color pickers often express the color values in hexadecimal as well. Throughout the lessons in the tutorial you'll learn of other ways to use hexadecimal numbers in your coding.

I know, I fudged the facts a little:

For those of you with knowledge on this subject you'll know I left out many important details that were used in the programming of those early computers. Those details are well beyond the scope of this lesson however.

Using a Programmer's Calculator

Performing conversions between these number systems can be tedious and time consuming. The important thing here is that you understand the differences between these number systems. To make life easier you can use a calculator that supports programmer functions. One such calculator happens to come with Windows, the humble Windows Calculator.

Figure 1: Windows Calculator

Note: The version of Windows calculator shown here is from Windows 7 Professional. If you are using Windows 10 or 11 and wish to have this version see the section at the bottom of the lesson where I explain how you can do this.

The Windows Calculator supports four modes: Standard, Scientific, Programmer, and Statistics. You can click on View in the menu to select which mode you wish to be in as shown in Figure 2 below:

Figure 2: Choose your mode

Go ahead and click on programmer to bring up the programmer's interface.

Figure 3: The calculator's programmer's interface

There are four BASEs you can work in, Hex (hexadecimal), Dec (decimal), Oct (octal), and Bin (binary). Octal is a BASE8 numbering system that was popular back in the early days of computing and is rarely used today. Figure 3 above points out where these base radio buttons are located.

Above the calculator buttons you will see 64 binary places labeled 0 through 15 through 31 on the bottom row (the first 32 bits) and then 32 through 47 through 63 on the top row (the second 32 bits for a total of 64 bits). You will always see a binary representation of the number you are working with regardless of the BASE currently chosen and displayed in the calculator window.

Using the radio buttons to change the binary bit length between Qword (quad word 64 bits), Dword (double word 32 bits), Word (16 bits), and Byte (8 bits), will adjust the amount of binary places seen over the calculator keys.

To convert a number from one BASE to another simply choose the BASE radio button of the number you wish to convert, type in the number, and then choose the BASE radio button you wish to convert the number to.

Figure 4: Converting the decimal number 181 to hexadecimal

Figure 4 above illustrates how the decimal number 181 was typed in while the BASE radio button Dec is selected and then clicking on the Hex BASE radio button to convert 181 to the hexadecimal number B5. You can use this procedure to convert numbers between any of the four BASEs available. Also, notice that when the Hex BASE radio button is chosen the A, B, C, D, E, and F calculator keys are available. Remember hexadecimal numbers use A through F to represent 10 through 15.

The remaining unfamiliar calculator keys are used for bit shifting and bit logic. Their uses are beyond the scope of this lesson but for the curious they perform the following functions:

Mod - MODulus Division: return the remainder of a division.

RoL - Rotate Left: All bits in the number are shifted to the left one place with the leftmost bit moving to the rightmost position.

RoR - Rotate Right: All bits in the number are shifted to the right one place with the rightmost bit moving to the leftmost position.

Lsh - Left Shift: all bits in the number of shifted to the left one place with the leftmost bit being dropped.

Rsh - Right Shift: all bits in the number are shifted to the right one place with the rightmost bit being dropped.

Or  - Logical Bitwise OR: two numbers are ORed at the bit level.

Xor - Logical Bitwise XOR: two numbers are XORed at the bit level.

And - Logical Bitwise AND: two numbers are ANDed at the bit level.

Not - Logical Bitwise NOT: all bits in a number are flipped to their opposite value.

I Want the Windows 7 Calculator

The Windows 10 and 11 versions of the calculator are now "apps" whatever the heck that means in Microsoft's world. People have reported slow response when trying to load the calculator "app" or when using it. Many have reported that they hacked in the Windows 7 calculator and couldn't he happier. Here is how they did it. (This will not affect your current calculator "app")

You'll need these two files from a Windows 7 computer:

c:\windows\system32\calc.exe
c:\windows\system32\en-US\calc.exe.mui

If you don't have access to a Windows 7 computer here are the two files from one of my Windows 7 computers.

Windows7Calculator.ZIP

Create a folder anywhere you like. I would suggest on the Desktop and name it Windows 7 Calculator.

Note: The secondary folder called en-US will depend on your Windows localization. For example if you have a German version of Windows you would create a de-DE folder instead of en-US. I don't know all the localization folder names so you'll need to do a little research to determine yours.

Concepts Learned in this Lesson