DSPRelated.com
Blogs

A Recipe for a Common Logarithm Table

Cedron DawgApril 29, 2017

Introduction

This is an article that is a digression from trying to give a better understanding to the Discrete Fourier Transform (DFT).

A method for building a table of Base 10 Logarithms, also known as Common Logarithms, is featured using math that can be done with paper and pencil. The reader is assumed to have some familiarity with logarithm functions. This material has no dependency on the material in my previous blog articles.

If you were ever curious about how logarithm tables could be compiled before computers or calculators, keep reading, this article offers one explanation.

Logarithmic Scales

Because we use a base 10 number system, a base 10 logarithm is the one usually learned first and used most often. The nice thing is that only the logarithms of 1 through 10 need to be listed in a table to get a full range of values. The Base 10 logarithm is known as the Common Logarithm because of its prevalence. The other main logarithm is known as Natural Logarithms which has a base of $ e $. Using a common logarithm versus a natural logarithm is somewhat analogous to using degrees versus radians in angle measurements. One scale is convenient numerically and the other is the one that occurs most plainly in the math.

Real valued logarithmic scales can be built using any positive real base value except for 1. In Digital Signal Processing (DSP) there are two other logarithmic scales that are often used. The first is decibels (dB), which is generally used to measure ratios, has a base of $ 10^\frac{1}{10}$. The second is semitones on a chromatic music scale, used to measure frequency, having a base of $ 2^\frac{1}{12}$. Although these are both logarithm scales and are thus theoretically interchangeable, they are never mixed. You are not likely to hear that a decibel is about a four semitone interval.

Notational Conventions

Logarithms of different bases are usually denoted as "$ \log_{base} $". In this article, the convention will be that "$ \lg $" will denote a base 10 log. The word "log" will be used for "logarithm" in general. The base of the log will be known by the context, but it will usually be 10. $$ \lg(x) = \log_{10}(x) \tag {1} $$ The abbreviation "$ \ln $" will be used for natural logs. $$ \ln(x) = \log_{e}(x) \tag {2} $$ This convention differs from function names in programming languages. In C/C++, the function names are "log10" for common logarithms and "log" for natural logarithms.

Some Logarithm Rules

This is the fundamental property of logarithms. It is true for any base. $$ \log(x \cdot y) = \log(x) + \log(y) \tag {3} $$ The repeat version is true. The repeats can even be fractional. $$ \log(x^k) = k \cdot \log(x) \tag {4} $$ Logarithms can be translated from one base to another using a conversion factor. For this article, conversion from natural logs to common logs is needed. $$ x = e ^ { \ln(x) } = \left( 10^{\lg(e)} \right) ^ { \ln(x) } = 10^{ \lg(e) \cdot \ln(x) } \tag {5} $$ Taking the log of the left and right sides: $$ \lg(x) = \lg(e) \cdot \ln(x) \tag {6} $$ This gives the equation to convert natural log values to common log values. The conversion factor is $ \lg(e) $ which has a fixed value that will be calculated along the way.

The Series that are Needed

The recipe in this article will require having the value of $ e $. This can be found using the Taylor series for $ e^x $. $$ e^x = 1 + x + \frac{x^2}{2} + \frac{x^3}{3!} + \frac{x^4}{4!} + \frac{x^5}{5!} + ... \tag {7} $$ Not suprisingly, this series for a natural log will be used a lot. $$ \ln( 1 + x ) = x - \frac{x^2}{2} + \frac{x^3}{3} - \frac{x^4}{4} + \frac{x^5}{5} + ... \tag {8} $$

The Common Logarithm of 1

The logarithm of 1 in any base is 0. This follows directly from (3). $$ \lg( 1 ) = \lg( 1 \cdot 1) = \lg(1) + \lg(1) \tag {9} $$ Subtracting $ \lg(1) $ from both sides and reversing them gives: $$ \lg(1) = 0 \tag {10} $$

The Common Logarithm of 2

This is a little trickier and requires some work. It would be possible to calculate $ \ln(2) = \ln( 1 + 1 ) $ using the series solution, but it would converge horrendously slowly requiring many calculations. After that, $ \lg(e) $ would still be needed to convert it to $\lg(2)$.

Instead, a close coincidence will be exploited. $$ 2^{10} = 1024 = 1000 \cdot ( 1 + .024 ) \tag {11} $$ Take the log of both sides. $$ \lg(2^{10}) = \lg(1000) + \lg( 1 + .024 ) \tag {12} $$ Simplify and put in a calculable form using the rules of logarithms. $$ 10 \cdot \lg(2) = 3 + \lg(e) \cdot \ln( 1 + .024 ) \tag {13} $$ To simplify the equations going forward, the natural log expression will get a substitute name. $$ S_2 = \ln( 1 + .024 ) \tag {14} $$ The value $ S_2 $ can be calculated to any desired degree of accuracy using (8).

The $ \lg(2) $ can be solved for by dividing both sides of (13) by 10. $$ \lg(2) = \frac{3}{10} + \frac{1}{10} \cdot \lg(e) \cdot S_2 \tag {15} $$ Since $ \lg(e) $ remains unknown, the value of $ \lg(2) $ can't be calculated quite yet.

The Common Logarithm of 3

A similar trick is used to find the $\lg(3)$. The processing steps are the same as for the $\lg(2)$ case. $$ 3^4 = 81 = 80 \cdot \left( 1 + \frac{1}{80} \right) \tag {16} $$ $$ \lg(3^4) =\lg(80) + \lg \left( 1 + \frac{1}{80} \right) \tag {17} $$ $$ 4 \cdot \lg(3) = 1 + 3 \cdot \lg(2) + \lg(e) \cdot \ln \left( 1 + \frac{1}{80} \right) \tag {18} $$ $$ S_3 = \ln \left( 1 + \frac{1}{80} \right) \tag {19} $$ $$ \lg(3) = \frac{1}{4} + \frac{3}{4} \cdot \lg(2) + \frac{1}{4} \cdot \lg(e) \cdot S_3 \tag {20} $$ The series sum $ S_3 $ can be calculated to any desired degree of accuracy. $ \lg(e) $ remains unknown, and so does $ \lg(2) $. The latter can be replaced by the former using (15) leaving $ \lg(e) $ as the only unknown. $$ \lg(3) = \frac{1}{4} + \frac{3}{4} \cdot \left[ \frac{3}{10} + \frac{1}{10} \cdot \lg(e) \cdot S_2 \right] + \frac{1}{4} \cdot \lg(e) \cdot S_3 \tag {21} $$ $$ \lg(3) = \frac{1}{4} + \frac{9}{40} + \frac{3}{40} \cdot \lg(e) \cdot S_2 + \frac{1}{4} \cdot \lg(e) \cdot S_3 \tag {22} $$ $$ \lg(3) = \frac{19}{40} + \lg(e) \cdot \left( \frac{3}{40} \cdot S_2 + \frac{1}{4} \cdot S_3 \right) \tag {23} $$

The Common Logarithm of $e$

Finally, it is time to calculate the value of $ \lg(e) $. One way is to use (6) with $ x = 10 $. $$ 1 = \lg(e) \cdot \ln(10) \tag {24} $$ Therefore: $$ \lg(e) = \frac{1}{\ln(10)} \tag {25} $$ The value of $ \ln(10) $ can be found by repeatedly taking the square root of the square root of the square root of ten until it takes the form $ (1 + x) $ where x is fairly small. Taking the square root eight times should be enough. $$ (((((((10^{\frac{1}{2}})^{\frac{1}{2}})^{\frac{1}{2}})^{\frac{1}{2}})^{\frac{1}{2}})^{\frac{1}{2}})^{\frac{1}{2}})^{\frac{1}{2}} = 10^{\frac{1}{256}} \tag {26} $$ $$ \ln(10) = 256 \cdot \ln( 10^{\frac{1}{256}} ) \approx 256 \cdot \ln( 1 + .009035045 ) \tag {27} $$ A series still needs to be calculated and then a reciprocol taken. That's a lot of work.

There is a better way that doesn't require nearly as many calculations. It is sort of similar to the technique used for $ \lg(2) $ and $ \lg(3) $.

Before that can be done, a value for $ e $ is needed. For this, the series in (7) is used with $ x = 1 $. $$ \begin{aligned} e &= e^1 = 1 + 1 + 1/2 + 1/3! + 1/4! + 1/5! + ... \\ &= 2.71828182845.... \\ &= 2.7 + .01828182845.... \\ &= 2.7 \cdot ( 1 + .00677104757.... ) \end{aligned} \tag {28} $$ Notice how it is split out into a product of a number and a $ ( 1 + x ) $ expression where $ x $ is small. Taking the log of both sides leads to a formula for $ \lg(e) $: $$ \lg(e) = \lg(2.7) + \lg(e) \cdot \ln( 1 + .00677104757.... ) \tag {29} $$ Again, the series summation is given a substitute name. $$ S_e = \ln( 1 + .00677104757.... ) \tag {30} $$ Since $ 2.7 = 27/10 = 3^3 / 10 $: $$ \lg(e) = -1 + 3 \cdot \lg(3) + \lg(e) \cdot S_e \tag {31} $$ The formula for the unknown value $\lg(3)$ can be plugged in. $$ \lg(e) = -1 + 3 \cdot \left[ \frac{19}{40} + \lg(e) \cdot \left( \frac{3}{40} \cdot S_2 + \frac{1}{4} \cdot S_3 \right) \right] + \lg(e) \cdot S_e \tag {32} $$ $$ \lg(e) = -1 + \frac{57}{40} + \lg(e) \cdot \left( \frac{9}{40} \cdot S_2 + \frac{3}{4} \cdot S_3 \right) + \lg(e) \cdot S_e \tag {33} $$ $$ \lg(e) = \frac{17}{40} + \lg(e) \cdot \left( \frac{9}{40} \cdot S_2 + \frac{3}{4} \cdot S_3 + S_e \right) \tag {34} $$ Now comes the twist that completes the bootstrap. The only remaining unknown is $\lg(e)$ and it can be solved for. $$ \lg(e) \cdot \left( 1 - \frac{9}{40} \cdot S_2 - \frac{3}{4} \cdot S_3 - S_e \right) = \frac{17}{40} \tag {35} $$ $$ \lg(e) = \frac{17}{40} \cdot \frac{1}{ 1 - \frac{9}{40} \cdot S_2 - \frac{3}{4} \cdot S_3 - S_e } \tag {36} $$ $$ \lg(e) = \frac{17}{ 40 - 9 \cdot S_2 - 30 \cdot S_3 - 40 \cdot S_e } \tag {37} $$ The final right side has only integers and the results of series summations. The summations can be taken to any degree of accuracy, therefore the value of $ \lg(e) $ can be calculated to any desired accuracy.

The Common Logarithms of 4 through 10

Now that $ \lg(e) $ is known to sufficient accuracy, the values of $ \lg(2) $ and $ \lg(3) $ can be calculated using (15) and (23).

After that, calculating the next few values is easy. $$ \lg(4) = 2 \cdot \lg(2) \tag {38} $$ $$ \lg(5) = \lg(10/2) = \lg(10) - \lg(2) = 1 - \lg(2) \tag {39} $$ $$ \lg(6) = \lg(2) + \lg(3) \tag {40} $$ In order to calculate the common logarithm of seven, some more work is needed. The same approach as with two and three works for seven. $$ 7^4 = 2401 = 2400 \cdot \left( 1 + \frac{1}{2400} \right) \tag {41} $$ $$ 4 \cdot \lg(7) = 2 + 3 \cdot \lg(2) + \lg(3) + \lg \left( 1 + \frac{1}{2400} \right) \tag {42} $$ $$ \lg(7) = \frac{1}{4} \cdot \left[ 2 + 3 \cdot \lg(2) + \lg(3) + \lg(e) \cdot \ln \left( 1 + \frac{1}{2400} \right) \right] \tag {43} $$ Finishing up to ten is easy too. $$ \lg(8) = 3 \cdot \lg(2) \tag {44} $$ $$ \lg(9) = 2 \cdot \lg(3) \tag {45} $$ $$ \lg(10) = 1 \tag {46} $$

Common Logarithms from Neighboring Values

There is a version of the factoring trick that works for any $ N $. $$ \begin{aligned} N^2 &= ( N^2 - 1 ) + 1 \\ &= ( N^2 - 1 ) \cdot \left[ 1 + \frac{1}{N^2-1} \right] \\ &= ( N - 1 ) \cdot ( N + 1 ) \cdot \left[ 1 + \frac{1}{N^2-1} \right]\\ \end{aligned} \tag {47} $$ Take the log of both sides and solve for $ \lg(N) $. $$ 2 \cdot \lg(N) = \lg(N-1) + \lg(N+1) + \lg \left( 1 + \frac{1}{N^2-1} \right) \tag {48} $$ $$ \lg(N) = \frac{1}{2} \left[ \lg(N-1) + \lg(N+1) + \lg(e) \cdot \ln\left( 1 + \frac{1}{N^2-1} \right) \right] \tag {49} $$ The log value is based on the log values of its neighbors $ N - 1 $ and $ N + 1 $. This will only be used for prime numbers in the algorithm. All the logs of composite numbers can be calculated by adding the logs of two factors.

The advantage of this method over one based on just using $ N - 1 $ is that the resulting $ \ln( 1 + x ) $ converges much faster.

The Algorithm

From here on out the calculations are carried out in an algorithmic manner. The numbers aren't going to be processed in strict order. Whenever a prime number is encountered, the next number (which will be even) has to be processed first.

Here is the pseudo-code for the algorithm:

If N Is Even Then
   If N Is A Multiple Of Ten Then
      lg(N) = 1 + lg(N/10)
   Else
      lg(N) = lg(2) + lg(N/2)
   End If
Else
   If N Is Not Prime Then
      N = A*B
      lg(N) = lg(A) + lg(B)
   Else
      Calculate lg(N+1) Using the Even Case
      lg(N) = [lg(N-1)+lg(N+1)+lg(e)*ln(1+1/(N^2-1))]/2
   End If
End If

The Common Logarithms of 11 and up

Continue with the calculations according to the algorithm: $$ \lg(12) = \lg(2) + \lg(6) \tag {50} $$ $$ \lg(11) = \frac{1}{2} \cdot \left[ 1 + \lg(12) + \lg(e) \cdot \ln \left( 1 + \frac{1}{120} \right) \right] \tag {51} $$ $$ \lg(14) = \lg(2) + \lg(7) \tag {52} $$ $$ \lg(13) = \frac{1}{2} \cdot \left[ \lg(12) + \lg(14) + \lg(e) \cdot \ln \left( 1 + \frac{1}{168} \right) \right] \tag {53} $$ $$ \lg(15) = \lg(3) + \lg(5) \tag {54} $$ $$ \lg(16) = \lg(2) + \lg(8) \tag {55} $$ $$ \lg(18) = \lg(2) + \lg(9) \tag {56} $$ $$ \lg(17) = \frac{1}{2} \cdot \left[ \lg(16) + \lg(18) + \lg(e) \cdot \ln \left( 1 + \frac{1}{288} \right) \right] \tag {57} $$ $$ \lg(20) = 1 + \lg(2) \tag {58} $$ $$ \lg(19) = \frac{1}{2} \cdot \left[ \lg(18) + \lg(20) + \lg(e) \cdot \ln \left( 1 + \frac{1}{360} \right) \right] \tag {59} $$ $$ \lg(21) = \lg(3) + \lg(7) \tag {60} $$ $$ \lg(22) = \lg(2) + \lg(11) \tag {61} $$ $$ \lg(24) = \lg(2) + \lg(12) \tag {62} $$ $$ \lg(23) = \frac{1}{2} \cdot \left[ \lg(22) + \lg(24) + \lg(e) \cdot \ln \left( 1 + \frac{1}{528} \right) \right] \tag {63} $$ $$ \lg(25) = \lg(5) + \lg(5) \tag {64} $$ and so on.....

As N gets larger, the frequency of primes numbers becomes lower and the $ ln( 1 + x ) $ series converge faster.

Building a Lookup Table

When the list reaches 99, the following table can be produced:

     .0   .1   .2   .3   .4   .5   .6   .7   .8   .9
  1 0000 0414 0792 1139 1461 1761 2041 2304 2553 2788
  2 3010 3222 3424 3617 3802 3979 4150 4314 4472 4624
  3 4771 4914 5051 5185 5315 5441 5563 5682 5798 5911
  4 6021 6128 6232 6335 6435 6532 6628 6721 6812 6902
  5 6990 7076 7160 7243 7324 7404 7482 7559 7634 7709
  6 7782 7853 7924 7993 8062 8129 8195 8261 8325 8388
  7 8451 8513 8573 8633 8692 8751 8808 8865 8921 8976
  8 9031 9085 9138 9191 9243 9294 9345 9395 9445 9494
  9 9542 9590 9638 9685 9731 9777 9823 9868 9912 9956

Using the values of the entries from 10 to 99, strip off the leading "1." This saves a lot of display width in the table. For four digits, like this example, the values should have been calculated out to six significant digits and then rounded. Stripping the leading one is the same as subtracting one. For a common log scale, this the same as dividing by 10. This now makes the list of values the logs of 1.0 to 9.9 with a .1 step.

When the list reaches 999, a more detailed table can be made:

    .00  .01  .02  .03  .04  .05  .06  .07  .08  .09
1.0 0000 0043 0086 0128 0170 0212 0253 0294 0334 0374
1.1 0414 0453 0492 0531 0569 0607 0645 0682 0719 0755
1.2 0792 0828 0864 0899 0934 0969 1004 1038 1072 1106
1.3 1139 1173 1206 1239 1271 1303 1335 1367 1399 1430
1.4 1461 1492 1523 1553 1584 1614 1644 1673 1703 1732
1.5 1761 1790 1818 1847 1875 1903 1931 1959 1987 2014
1.6 2041 2068 2095 2122 2148 2175 2201 2227 2253 2279
1.7 2304 2330 2355 2380 2405 2430 2455 2480 2504 2529
1.8 2553 2577 2601 2625 2648 2672 2695 2718 2742 2765
1.9 2788 2810 2833 2856 2878 2900 2923 2945 2967 2989
2.0 3010 3032 3054 3075 3096 3118 3139 3160 3181 3201
.
.
.

In this case, the list values from 100 to 999 have the leading "2." stripped making the effective domain from 1.00 to 9.99. This table has fine enough resolution that linear interpolation will work quite well.

Published Logarithm tables will generally have some type of interpolation parameters off to the right of the main body of numbers. Check the key to see what they are and how to use them.

Very Accurate Interpolation

Suppose a list of 1000 log values was calculated out to twenty decimal places. Is it possible to get an interpolated value that is also accurate to twenty decimal places?

The answer is yes. The method is similar to what has already been done repeatedly. Suppose $v$ is the value for which the log value is sought. Let $x$ be the closest entry in the log table. Their difference can be called $d$. $$ d = v - x \tag {65} $$ Rearranging a little bit and taking the log leads to the interpolation equation. $$ \begin{aligned} \lg(v) &= \lg(x + d) \\ &= \lg \left[ x \cdot \left(1 + \frac{d}{x} \right) \right] \\ &= \lg(x) + \lg \left(1 + \frac{d}{x} \right) \\ &= \lg(x) + \lg(e) \cdot \ln \left(1 + \frac{d}{x} \right) \end{aligned} \tag {66} $$ The value of $ d $ will always be less than or equal to half the step size of the table. For the current example with a step size of .01 that bound is .005. The natural log series will converge by at least two decimal places for each additional term calculated.

Very Accurate Inverses

It is also possible to use the log table for finding inverse logs. Only the ability to find the inverse logs of any value from zero to one is needed to be able to find any value whatsoever. Any value can be split into an integer portion ($n$) and a fractional portion ($y$) $$ 10^{n+y} = 10^n \cdot 10^y \tag {67} $$ The inverse log need only be calculated for the fractional portion and then the $n$ is used to tell how many places to shift the decimal point.

The first step is to search the log table for where the log value is closest to the fraction $y$. Once this is found, the corresponding $x$ can be determined by the table indexes. Obviously, the $lg(x)$ value has also been found. $$ y = lg(x) + s = \lg(x + d) \tag {68} $$ The answer being sought is $x+d$. $$ 10^y = x + d = x \cdot 10^s \tag {69} $$ $$ x + d = x \cdot (e^{\ln(10)})^s \tag {70} $$ $$ x + d = x \cdot e^{[y-\lg(x)]\ln(10)} = x \cdot e^z \tag {71} $$ The value of $x+d$ can be found by the product of $x$ and the series sum of $z$ in (7). $$ z = \left[ y - \lg(x) \right] \cdot \ln(10) \tag {72} $$ The absolute value of $z$ should be much smaller than one, so the series evaluation will converge much quicker than the calculation of $e$ in (28).

The value of $\ln(10)$ can be found using (25) and (37). $$ \ln(10) =\frac{1}{ \lg(e) } = \frac{ 40 - 9 \cdot S_2 - 30 \cdot S_3 - 40 \cdot S_e }{17} \tag {73} $$ The numerator on the right hand side is already known from calculating (37). Therefore the right hand side is much easier to do by hand since only division by a two digit number is called for.

To recap, find the $x$ with the closest $\lg(x)$ to $y$, calculate $z$, calculate $e^z$, then multiply the result by $x$.

Conclusion

A table of common logarithms can be whipped up from scratch with calculations that can be done by hand. The only ingredients were a few logarithm rules and a couple of series definitions. Thankfully, doing square roots by hand was not needed.

A logarithm table can also be used for finding the inverse logarithms.

Understanding how common logarithms work is a prerequisite to understanding how a slide rule works.

Disclaimer: None of the displayed values in this article were calculated by hand.

Appendix A - Log Values

lg(1) = 0.000000000000000  =  0
lg(2) = 0.301029995663981 ~=~ 3/10                 =  .3
lg(3) = 0.477121254719662 ~=~ 19/40                =  .475
lg(4) = 0.602059991327962  =  2 * lg(2)           ~=~ .6
lg(5) = 0.698970004336019  =  1 - lg(2)           ~=~ .7
lg(6) = 0.778151250383644  =  lg(2) + lg(3)       ~=~ .775 
lg(7) = 0.845098040014257 ~=~ [2+3*lg(2)+lg(3)]/4 ~=~ .84375
lg(8) = 0.903089986991943  =  3 * lg(2)           ~=~ .9
lg(9) = 0.954242509439325  =  2 * lg(3)           ~=~ .95
lg(e) = 0.434294481903252

Appendix B - Sum Results

 S2   = ln( 1 + .024 )      = 0.023716526617316
 S3   = ln( 1 + 1/80 )      = 0.012422519998557
 Se   = ln( 1 + (e/2.7-1) ) = 0.006748226989717
 S7   = ln( 1 + 1/2400 )    = 0.000416579885216
 S11  = ln( 1 + 1/120 )     = 0.008298802814695
 S13  = ln( 1 + 1/168 )     = 0.005934735519815
 S17  = ln( 1 + 1/288 )     = 0.003466207976486
 S19  = ln( 1 + 1/360 )     = 0.002773926882725
 S23  = ln( 1 + 1/528 )     = 0.001892148152038


To post reply to a comment, click on the 'reply' button attached to each comment. To post a new comment (not a reply to a comment) check out the 'Write a Comment' tab at the top of the comments.

Please login (on the right) if you already have an account on this platform.

Otherwise, please use this form to register (free) an join one of the largest online community for Electrical/Embedded/DSP/FPGA/ML engineers: