We can represent a number in any base >= 2, since we need at least 2 different values to distinguish a digit. Names of the first 15 number bases are given in Table 14.3, “”.
Table 14.3.
Base | Name |
---|---|
2 | Binary |
3 | Ternary |
4 | Quaternary |
5 | Quinary |
6 | Senary |
7 | Septenary |
8 | Octal |
9 | Nonary |
10 | Decimal |
11 | Undecimal |
12 | Duodecimal |
13 | Tridecimal |
14 | Tetradecimal |
15 | Pentadecimal |
16 | Hexadecimal |
In computer science, the most useful bases are 2, 8, and 16. The reasons for this will become clear in the following sections.
The digits for any given number base range from 0 to base-1. As we know, base 10 uses digits 0 to 9. Base 8 (octal) uses 0 to 7 and base 2 (binary) uses 0 to 1. Using larger digits would make it possible to represent a value in more than one way. For example, if binary fixed point allowed the use of the digit '2', then the number two could be represented as either '2' or '10'.
1001.11_{2} = 1 * 2^{3} + 1 * 2^{0} + 1 * 2^{-1} + 1 * 2^{-2} = 8 + 1 + 1/2 + 1/4 = 9.75_{10}
34.5_{8} = 3 * 8^{1} + 4 * 8^{0} + 5 * 8^{-1} = 24 + 4 + 5/8 = 28.625_{10}
12.0_{2} and 80.6_{8} are not valid numbers.
For bases larger than 10, we use letters for digits greater than 9: A = 10, B = 11, C = 12, D = 13, E = 14, F = 15
3F.8_{16} = 3 * 16^{1} + 15 * 16^{0} + 8 * 16^{-1} = 48 + 15 + 8/16 = 63.5_{10}
The easiest conversion is binary to decimal. In this case we are dealing with powers of 2, which are easy, and multiplying by either 0 or 1, since those are the only possible digits. So, if there's a 1, we add that power of 2 and if there's a 0, we don't.
One method is scanning left to right, doubling the sum so far for each new digit (whether 0 or 1) and adding the next digit to the sum.
1101_2 1) 1 (leftmost digit) 2) 2 + 1 = 3 3) 6 + 0 = 6 4) 12 + 1 = 13
This method is easy to program since it reads the string of 0s and 1s from left to right, which is how they would arrive from a file or a keyboard. We don't need to store the digits in an array.
sum = 0; while ( (ch = getchar()) != '\n' ) sum = sum * 2 + ch - '0';
When converting by hand, you may find it more intuitive to go from right to left, doubling the value we add (the power of 2) each at step and then only adding if the digit is 1.
1101_2 = 1 + 0 + 4 + 8 = 13
As converting to decimal is a process of adding and multiplying, converting from decimal to other bases is naturally a matter of dividing and subtracting. The basic left-to-right method is as follows:
Example 14.3. Conversion from Decimal
439.5_{10} to binary, octal, hexadecimal, and base 5.
Binary Octal Hex Base 5 110110111.1 667.4 1B7.8 3224.222 +------------ +---- +------ +--------- 256 | 439.5 64 | 439.5 256 | 439.5 125 | 439.5 256 384 256 375 +----- +---- +----- +---- 128 |183.5 8 |55.5 16 |183.5 25 |64.5 128 48 176 50 +---- +--- +---- +---- 64 |55.5 1 |7.5 1 | 7.5 5 |14.5 0 7 7 10 +---- +--- +--- +--- 32 |55.5 1/8|0.5 1/16|0.5 1 |4.5 32 0.5 0.5 4 +---- --- --- +--- 16 |23.5 0 0 1/5|0.5 16 0.4 +--- +--- 8 |7.5 1/25|0.1 0 0.08 +--- +---- 4 |7.5 1/125|0.02 4 0.016 +--- +----- 2 |3.5 |0.004 2 (repeats) +--- 1 |1.5 1 +--- 1/2|0.5 0.5 --- 0
We can also work in the other direction (from right to left) by repeatedly dividing by the base (using integer division) and taking the remainder as the next digit to the left. Here we stop as soon as we get a quotient of 0.
Example 14.4. 37_{10} to binary
Decimal to binary 37_10 = 100101_2 37/2 = 18 r1 1 18/2 = 9 r0 01 9/2 = 4 r1 101 4/2 = 2 r0 0101 2/2 = 1 r0 00101 1/2 = 0 r1 100101_2
What are the names for base 2, base 8, and base 16?
Perform each of the following conversions using the method of your choice.
100101_2 to decimal
234_8 to decimal
FC1_16 to decimal
32_10 to binary
129_10 to octal
129_10 to hexadecimal