Wednesday, September 21, 2011

A Review of the Hexadecimal Number System

Introduction

Humans were born with ten fingers on their hands (if you include the thumb as a finger), so it is natural that the first humans invented a counting system that went from one to ten, from counting on their fingers. In fact, the word digit derives from the Latin root for "ten" and is used to mean both a single number between 0 and 9, and a finger or thumb (or toe).

Computers and digital electronics, on the other hand, deal with two states:  on/off, one/zero, plus/minus. Since a computer digit can have only two values, it is called a "binary digit," or bit for short.

Binary arithmetic is very useful. You can count on your fingers in binary, all the way up to 1023. But counting in binary quickly gets cumbersome, and so most binary arithmetic is done in hexadecimal.

"Hexadecimal" is a word derived from the Latin roots for six ("hexa-") and ten ("decimal"). It is a form of expressing numbers in base sixteen. "Hexadecimal" is often abbreviated to "hex."

The Decimal System as an Example of Counting Systems

As we said in the introduction, most human beings count in the decimal, or base-ten, number system. In base ten, you use the numerals from 0 to 9. To count past nine, you need some way to indicate the overflow, so you use a second digit - the "tens" digit - to count the "number of overflows."  Likewise, when you run out of digits to express the overflows, you add a third digit - a "hundreds" digit, to count the "overflows of overflows" - and so on, until you have enough digits to express any given number.

So, proceeding from right to left, the first digit represents the number of "ones," or 10^0, in the number; the second digit represents the number of whole sets of ten (10^1); the third digit represents the number of whole
sets of a hundred (10^2), etc. Thus, the nth digit represents the number of whole sets of 10^(n-1) in the number.

(This blog doesn't allow for superscripts, so the ^ symbol is used to indicate an exponent, or "raised to the power of ...")

So you could think of the number 3401 as:

3x10^3 + 4x10^2 + 0x10^1 + 1x10^0

Significant Digits

Obviously, changing the leftmost digit in the number has a greater effect on the number than changing the rightmost digit. That is, the leftmost digit is the most significant digit; and the rightmost digit is the least significant digit. For example, if you see a house selling for $293,499 and one selling for $293,500, you'd say that they both cost the same. One dollar isn't very significant compared to two hundred ninety thousand dollars.

The right-to-left order of increasing significance is a convention used in other place-value numbering systems, including binary and hexadecimal.

Hexadecimal Values

Computers count in binary, using only the numerals 0 and 1. That's difficult for humans to comprehend and uses a lot of space in displays and printouts. A more convenient way to organize binary data is to group the bits together in groups of four, and assign each group a single value.

Look at the table below. You'll see that a group of four bits can range from 0000, with a value of zero, to 1111, with a value of fifteen. That's sixteen values, which is why sixteen - hexadecimal - is such a convenient number base to use when working with computers.

Of course, when expressing number values, you have only ten conventional Arabic numerals (0-9). But when counting in hexadecimal, you must go all the way to fifteen before adding a second numeral as a "counter of overflows." So the letters A-F are used as numerals to represent the values ten through fifteen in hexadecimal.

Decimal 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

(Some digital systems also use base eight, or octal, numbers. We'll ignore octal for now.)

What the Numbers Really Mean

Similar to the way decimal digits in a number represent different powers of ten (tens, hundreds, thousands, and so on), with the most significant digit on the left, hexadecimal digits in a number represent different powers of sixteen, with the most significant digit on the left. So you could think of the hexadecimal number C30F as:

12x16^3 + 3x16^2 + 0x16^1 +15x16^0

or, in decimal,

49,152 + 768 + 0 + 15 = 49,935

Most calculator and spreadsheet programs include built-in tools for converting back and forth between decimal, binary, and hexadecimal.

Decimal numbers use a separator (a comma in the Americas, a period in Europe) to group the digits and make them easier to read, such as:

12,345,678

Hexadecimal numbers use a space between pairs of hex digits, such as:

01 04 2A 59 FF F0

You may also see a dash or colon employed instead of a space. You may also occasionally see groups of four instead of pairs.

Binary numbers are easiest to read in groups of four:

1101 0100 0110 0001

A pair of hex digits represents 8 bits and is called a byte. Two bytes equal 16 bits, four bytes equal 32 bits, and so on. (Some programmers call a single hex digit, representing 4 bits, a nybble, but we'll ignore that for now.) If all the bits in a byte are ones, the byte will have a value of 255 (one less than 256, or 2^8).

A Practical Example

When reading Modbus registers or decoding SNMP objects, it's helpful to know how to extract the data from the byte string. For example, a Digital Power Meter outputs the two bytes "5C E1" to represent a voltage reading. The manufacturer's data sheet says that the bytes can be converted to a five-digit decimal number which, when divided by 100, gives the voltage in human readable form.

5C is 92, and E1 is 225. So 5C E1 converts to

92 x 256 + 225 x 1 = 23,777

Dividing by 100 yields a value of 237.77 volts.

One Last Note

When you're juggling numbers in different bases, you may get confused and forget whether 1000 represents eight, one thousand, or four thousand ninety-six.

Several conventions have arisen to distinguish between the bases in written form. Two common conventions are to write hex numbers with a "0x" prefix or an "h" suffix, such as 0x1000 or 1000h. Binary numbers are written with a "b" suffix", such as 1000b. Decimal numbers stand alone, without a suffix.

In speaking, every hex digit is pronounced individually. While the decimal number 128 is pronounced "one hundred twenty-eight," the hex number 128 is pronounced "one two eight." Further ambiguity can be avoided by saying "one two eight hex" or "hex one two eight."

(This article first appeared on the RLE Technologies community forum.  Parts of this article are from the book Graphics on the HP48G/GX. Used by permission of the author.)

No comments: