计算机如何算出平方根呢?最常用的就是牛顿的逐步逼进方法。这个方法就是:如果对x的平方根的值有一个猜测值y,那么就可以通过执行一个简单的操作去得到一个更好的猜测:只需要求出y和x/y的平均值(它更接近实际的平方根值)。例如,可以用这种方式去计算2的平方根,假定初始值是1:
猜想 商 平均值
1 2/1=2 (2+1)/2 = 1.5
1.5 2/1.5=1.3333 (1.3333+1.5)/2 = 1.4167
1.4167 2/1.4167=1.4118 (1.4167+1.4118)/2=1.4142
1.4142 ... ...
继续这一计算过程,我们就能得到对2的平方根的越来越好的近似值。
我们可以将这一基本策略写成下面的过程(schema):
(define (sqrt-iter guess x)
(if (good-enough? guess x)
guess
(sqrt-iter (improve guess x)
x)))
改进猜测的方法就是求出它与被开方数除以上一个猜测的平均值:
(define (improve guess x)
(average guess (/ x guess)))
其中:
(define (average x y)
(/ (+ x y) 2))
我们还必须说明什么叫做”足够好“,下面的做法想法是:不断改进答案直至它足够接近平均值,使得其平方与被平方数之差小于某个事先确定的误差值(这里是0.001):
(define (good-enough ? guess x)
(< (abs (-(square guess) x)) 0.001))
其中:
(define (square) x)
(* x x))
最后提供一个启动方法:
(define (sqrt x)
(sqrt-iter 1.0 x))
那么把这个定义都送给解释器,我们就可以使用sqrt,就像可以使用其他过程一样:
(sqrt 9)
3.00009155413138
(sqrt (+ 100 37))
11.704699917758145
(square (sqrt 1000))
1000.000369924366
这个过程也显示函数式运算思维与命令式的区别,这里是自顶向下的解决问题思路,而我们常用的命令式思维则要考虑如何指挥机器从底部一步一步的堆积出论证,最后达到我们的目标,是自底向上。