7.2 生成表格
循环非常适合用于生成和显示表格型数据。计算机还未面世时,人们必须手工计算对数、正弦、余弦等常见的数学函数。为简化这种工作,有些书提供了表格,让你能够查找各种函数的值,但手工创建这样的表格既缓慢又繁琐,并且结果常常错误百出。
计算机面世后,大家最初的反应之一是:太好了,可用计算机来生成这样的表格了,并确保它们没有任何错误。事实证明确实如此,但人们的目光还是太短浅了,不久后,计算机就非常普及,这些打印出来的表格也就被淘汰了。
但对于有些运算来说,计算机依然要先在值表中查找近似结果,再通过计算来提高结果的精度。然而,有些值表存在错误,其中最著名的是最初的 Intel 奔腾处理器用来计算浮点数除法的值表(参见 https://en.wikipedia.org/wiki/Pentium_FDIV_bug)。
虽然“对数表”不再像以前那么有用了,但它依然是迭代的典范。下面的循环显示了一个表格,其中左边一列是一系列值,而右边一列是这些值的对数:
int i = 1;while (i < 10) {double x = (double) i;System.out.println(x + " " + Math.log(x));i = i + 1;}
这个程序的输出如下:
1.0 0.02.0 0.69314718055994533.0 1.09861228866810984.0 1.38629436111989065.0 1.60943791243410036.0 1.7917594692280557.0 1.94591014905531328.0 2.07944154167983579.0 2.1972245773362196
Math.log 计算自然对数,即以 e 为底的对数。在计算机应用领域常常需要计算以 2 为底的对数,为此可使用下面的公式:

我们可将前面的循环修改成下面这样:
int i = 1;while (i < 10) {double x = (double) i;System.out.println(x + " " + Math.log(x) / Math.log(2));i = i + 1;}
结果如下:
1.0 0.02.0 1.03.0 1.58496250072115634.0 2.05.0 2.3219280948873626.0 2.5849625007211567.0 2.8073549220576048.0 3.09.0 3.1699250014423126
我们在每次循环中都将 x 的值加 1,从而得到一个等差数列。如果不将 x 加 1,而是乘以一个常数,将得到一个等比数列:
final double LOG2 = Math.log(2);int i = 1;while (i < 100) {double x = (double) i;System.out.println(x + " " + Math.log(x) / LOG2);i = i * 2;}
第 1 行将 Math.log(2) 存储在一个 final 变量中,以免反复计算这个表达式的值;最后一行将 x 乘以 2。结果如下:
1.0 0.02.0 1.04.0 2.08.0 3.016.0 4.032.0 5.064.0 6.0
这个表格列出了 2 的幂及其以 2 为底的对数。虽然对数表已毫无用处,但对计算机科学家来说,知道 2 的幂大有裨益!
