# 15.2: Generating Tables

Loops are good for generating and displaying tabular data. Before computers were readily available, people had to calculate logarithms, sines and cosines, and other common mathematical functions by hand. To make that easier, there were books of tables where you could look up values of various functions. Creating these tables by hand was slow and boring, and the results were often full of errors.

When computers appeared on the scene, one of the initial reactions was: “This is great! We can use a computer to generate the tables, so there will be no errors.” That turned out to be true (mostly), but shortsighted. Not much later, computers were so pervasive that printed tables became obsolete.

Even so, for some operations, computers use tables of values to get an approximate answer, and then perform computations to improve the approximation. In some cases, there have been errors in the underlying tables, most famously in the table the original Intel Pentium used to perform floating-point division (see https://en.Wikipedia.org/wiki/Pentium_FDIV_bug).

Although a “log table” is not as useful as it once was, it still makes a good example of iteration. The following loop displays a table with a sequence of values in the left column and their logarithms in the right column:

int i = 1;
while (i < 10) {
double x = i;
System.out.println(x + "   " + Math.log(x));
i = i + 1;
}

The output of this program is:

1.0   0.0
2.0   0.6931471805599453
3.0   1.0986122886681098
4.0   1.3862943611198906
5.0   1.6094379124341003
6.0   1.791759469228055
7.0   1.9459101490553132
8.0   2.0794415416798357
9.0   2.1972245773362196

Math.log computes natural logarithms, that is, logarithms base e. For computer science applications, we often want logarithms with respect to base 2. To compute them, we can apply this equation:

$\log_{2}{x} = \frac{\log_{e}{x}}{\log_{e}{2}} \nonumber$

We can modify the loop as follows:

int i = 1;
while (i < 10) {
double x = i;
System.out.println(x + "   " + Math.log(x) / Math.log(2));
i = i + 1;
}

And here are the results:

1.0   0.0
2.0   1.0
3.0   1.5849625007211563
4.0   2.0
5.0   2.321928094887362
6.0   2.584962500721156
7.0   2.807354922057604
8.0   3.0
9.0   3.1699250014423126

Each time through the loop, we add one to x, so the result is an arithmetic sequence. If we multiply x by something instead, we get a geometric sequence:

final double LOG2 = Math.log(2);
int i = 1;
while (i < 100) {
double x = i;
System.out.println(x + "   " + Math.log(x) / LOG2);
i = i * 2;
}

The first line stores Math.log(2) in a final variable to avoid computing that value over and over again. The last line multiplies x by 2. The result is:

1.0   0.0
2.0   1.0
4.0   2.0
8.0   3.0
16.0   4.0
32.0   5.0
64.0   6.0

This table shows the powers of two and their logarithms, base 2. Log tables may not be useful anymore, but for computer scientists, knowing the powers of two helps a lot!