Mindful Logarithm

Logarithm tables and slide rules used to be the mainstay of science and engineering: any moderately complex calculation (multiplication, division, power, square root, …) on floating point numbers can be efficiently tackled with such logarithm tables. Logarithm tables are impressively powerful tools. Producing large and accurate log-tables was a big job, and the resulting books containing those log-tables were standard on every scientist or engineer’s bookshelf.

The advent of affordable scientific calculators ended all that. Particularly the Hewlett-Packard HP-35 calculator, introduced in 1972, sounded the death knell for the widespread use of log-tables. These calculators had their own beautiful and sometimes miraculous algorithms built in and I reported on a particularly attractive algorithm in an earlier blog.

Class room demonstration slide rule. Prospectus photo downloaded from the slide rule museum website.

Going back to logarithms: can we produce a log-table from scratch? Let’s say, just using pen and paper?

This is an interesting exercise. You must remember that before the advent of digital computers such log-tables had to be constructed “by hand.” Let’s do it ourselves; all you need is pen and paper.

First off, we need to state that we are working with base-10 logarithms, simply written as “log”. Natural logarithms are written as “ln”.

Two entries in our log-table are going to be trivial: log(1) = 0 and log(10) = 1. These are the two extreme values of our log-table. All other numbers are related to numbers in this range by powers of 10, which have trivial logarithms. For example: log(512) = log(100) + log(5.12) = 2 + log(5.12). The last logarithm is in the range of our table.

Next, let’s try and find log(2). This turns out to be quite a bit of work, but having done the work, the rest of the log-table can be constructed fairly easily.

We are lucky: 210 = 1024. This means that 10 log(2) = log(1024) = 3 + log(1.024). The last term here is quite small, so we find that log(2) ≈ 0.3. But we must do better in order to get a useable log-table. Luckily, we can calculate log(1.024) quite accurately.

We will use the property of natural logarithms stating that ln(1+x) = x – x2/2 + x2/3 – … for small x. Converting this to base-10 logarithm we see that log(1+x) = (x – x2/2 + x2/3 – …) / ln(10). So in order to calculate log(1.024) we need to know ln(10).

OK, so how do we calculate ln(10)? The simplest way to do this is to try and calculate the integral over (1/x) for x between 1 and 10. You can use various numerical rules; a simple trapezoidal rule with steps of size 1 actually gives quite a decent result, and. interestingly, can be done pretty much in the head (can you sum 1/2 + 1/3 + 1/4 + … + 1/9 + (1+1/10)/2 in your head? I can.) The result is about ln(10) ≈ 2.37. The trapezoidal rule in this case will overestimate the value of the integral (because of the positive curvature of the (1/x) function), so we expect ln(10) to be a bit less than 2.37. In fact, it is easy to find some bounding values for the integral: it is less than (1/2 + 1/3 + … + 1/10) and more than (1 + 1/2 + … + 1/9). This bounds the result between 1.93 and 2.83; these are not particularly sharp bounds, but they will still be useful. (Note that the trapezoidal rule simply equals the average of these two bounds.) More accurate error bars can be found by looking at the convergence of the trapezoidal rule for more subdivisions; this is a somewhat tedious exercise, leading to a result that is around 2.3, but probably a bit bigger.

We can now go back to calculating log(1.024). It must be approximately 0.024 / ln(10) ≈ 0.01. If we used our rather poor upper or lower bounds in our calculation of ln(10) the result was the same at those significant digits. So we are pretty confident of this. Also: going to higher order in the expansion of ln(1+x) gives us a correction (downward) that is too small to change the 0.01.

We therefore find that to 3 significant digits log(2) = 0.301. This result trivially leads to several new entries in our table: log(4) = 2 log(2) = 0.602 and log(8) = 3 log(2) = 0.903. But also log(5) = log(10) – log(2) = 0.699. So our log table looks as follows:

10.000
20.301
40.602
50.699
80.903
101.000
log-table v. 0.1

It is not very impressive or useful yet. We can pad the table a bit more with entries for, for example, log(2.5) = log(5) – log(2), but let’s not follow that route now. We next want logarithms for all the integers between 1 and 10.

So, let’s try and calculate log(3). Because 34 = 81, we can see that 4 log(3) = log(10) + log(8) + log(1+1/80) = 1.903 + log(1.0125). This last term is quite small, and can be seen to be pretty much half of the small term log(1.024) we calculated before. We can therefore safely say that log(1.0125) ≈ 0.005. Any errors in this will be divided by 4, so we can be pretty content with this: log(3) ≈ (1.903 + 0.005) / 4 = 0.477 to 3 significant digits.

This result immediately leads to log(6) = log(3) + log(2) = 0.778 and log(9) = 2 log(3) = 0.954. Let’s see if we are still doing the right thing: log(1.0125) = log(81/80) = 4 log(3) – log(8) – log(10) = 0.005, as before; no rounding errors have been introduced.

Of course we can keep going with new fractional entries. For example log(1.5) = log(3) – log(2) = 0.176. Let us not yet fill in too many of those fractional entries although log(1.25) = log(10) – log(8) = 0.097 seems too obvious an entry to leave out at this stage.

Our new table looks like:

10.000
1.250.097
1.50.176
20.301
30.477
40.602
50.699
60.778
80.903
90.965
101.000
log-table v. 0.2

This is starting to look better. It is clear that quite a lot of fractional entries can be trivially produced. But there is this all too frustrating gap at log(7), the only remaining prime number below 10.

But we can uncover quite a nice and unexpected way of relating log(7) to logarithms that we already know. Instead of log(7) we are going to calculate log(49) = 2 log(7). But 49 is between 48 and 50, numbers that we know the logarithm of. It is trivial to see that 492 = 48 × 50 + 1. Simply omitting the 1 only makes a 1/2500 error. We therefore find that 2 log(49) ≈ log(48) + log(50) = 4 log(2) + log(3) + log(5) + log(10) = 2 + 3 log(2) + log(3) = 3.380. This leads to the rather neat and surprising result of log(7) ≈ (2 + 3 log(2) + log(3) ) / 4 = 0.845 to three significant digits. (I cheated at this stage and got my SwissMicros DM-42 calculator out to find that the error in this approximation is 0.000045 —not bad at all.)

The log(7) then gives access some more obvious fractional entries such as log(3.5) = log(7) – log(2). Let’s look at some of the other “half” fractions. We already did log(1.5) and log(2.5) and just saw log(3.5). The next one is log(4.5) = log(9) – log(2). The next one is log(5.5) = log(11) – log(2).

Unfortunately 11 is a prime number and would require a new calculation, which perhaps most easily would follow from 2 log(11) = log(121) = log(120) + log(1+1/120). The latter correction is 2/3 the size of the correction we used for the log(3) calculation log(1+1/80), so a bit more than 0.003. The logarithm log(120) is easily found to be 2.097 and a final estimate of log(11) = 1.041.

A more fun and potentially more accurate route suggests calculating log(99): 99 is between 98 and 100, numbers that we know the logarithms of. So we find, as before, 2 log(99) = 2 [log(9) + log(11)] ≈ log(98)+log(100) = log(2) + 2 log(7) + 2. The error in this approximation is very small; the result is the satisfyingly enigmatic log(11) ≈ 1+ [log(2) + 2 log(7)]/2 – 2 log(3) ≈ [6 + 5 log(2) – 7 log(3)]/4, where we used the above approximation for log(7). This last approximation is out from the true value for log(11) by about 0.000067, according to my calculator. It is amusing to see how different logarithms contain these enigmatic but in hindsight obvious connections.

The log(11) entry leads, for example, to further table entries for log(1.1) and log(5.5).

Those half fraction entries keep on bugging us: to calculate log(6.5) we need to know log(13), another prime number. The next entry log(7.5) = log(15) – log(2) is OK. For log(8.5) and log(9.5) we need to know logarithms of two further prime numbers log(17) and log(19). It is a fun challenge to come up with elegant and accurate pen-and-paper calculations for those primes.

OK, I can’t stop myself: 193 = 23×5×73 – 1. There: that should surely lead to an accurate calculation of log(19), and its various multiples and fractions.

Let’s finish with an abridged log-table including all key entries that we have achieved now:

10.000
1.10.041
1.250.097
1.50.176
20.301
30.477
40.602
50.699
60.778
70.845
80.903
90.965
101.000
log table v. 0.3

I have omitted most of the obvious fractions that you can add easily (stuff like 1.2, 1.4, 1.6, 1.8, 2.5, 3.5, 4.5, …) given the data in this table.

What we have achieved here is a reasonably dense and reasonably accurate log table using only very basic pen-and-paper calculations. Not so bad, it seems to me. It is not yet a practically useful table, to be honest. That would require the actual filling in of the gaps, but a rather large part of the gaps can be filled in using the above data. To get the resolution of the table down to entries with 0.1 increments throughout, then we need to calculate logarithms for all prime numbers up to a 100, but really, there are not that many gaps left.

(Most practical log-tables add an additional significant digit using linear interpolation between table entries, but this is only workable for a sufficiently dense table. The calculations are straightforward, if rather tedious.)

It would be nice to hear of clever ways to calculate the logarithm of some of those primes. I quite liked my own calculation of log(7), presented above, but I am less keen on my suggestion for log(19): it looks pretty accurate, but just a little bit tedious. There probably are more interesting methods for other primes. The trick is to keep the exercise at pen-and-paper level. Let me know if you find some interesting methods. To start with: what is log(13), log(17) and log(19)?

One thought on “Mindful Logarithm

Leave a comment