對(duì)于正文中的 good-enough? 謂詞,設(shè)所求 x 的真實(shí)平方根為 xt,那么我們的依據(jù)是當(dāng) guess 從 1 趨向與 xt 的平方差 小于 c(0.001) 時(shí),guess 近似于 xt。實(shí)際當(dāng) xt^2 也就是 x 足夠小時(shí), guess 會(huì) 逐漸穩(wěn)定在 √c 附近。從下面實(shí)驗(yàn)可以看出:
> (sqrt (square 0.1))
0.10032578510960607
> (sqrt (square 0.05))
0.054237622808967656
> (sqrt (square 0.01))
0.03230844833048122
> (sqrt (square 0.005))
0.031515954454847304
> (sqrt (square 0.001))
0.031260655525445276
> (sqrt (square 0.0001))
0.03125010656242753
>
因?yàn)?guess^2 < c + x
, 當(dāng) x < c 時(shí),guess 就更多的依賴于 c 了。
對(duì)于特別大的數(shù),由于浮點(diǎn)數(shù)在特別大時(shí),離散性非常明顯,相鄰的兩個(gè)數(shù)之間的差距會(huì)非常大,導(dǎo)致 |guess^2 - x| 始終 大于 c,計(jì)算便進(jìn)入了 無限循環(huán)。
比如計(jì)算 (sqrt 1e300)
使用變化率改進(jìn)后的代碼如下:
(define (sqrt-new x)
(sqrt-iter-new x 1.0 x))
(define (sqrt-iter-new s1 s2 x)
(if (enuf-new? s1 s2)
s2
(sqrt-iter-new s2 (improve s2 x) x)))
(define (enuf-new? s1 s2)
(< (/ (abs (- s1 s2)) s1) 0.001))
可以測(cè)算幾個(gè)數(shù),驗(yàn)證結(jié)果還是比較好的。
> (sqrt-new (square 1e150))
1.0000000000084744e+150
> (sqrt-new (square 1e-150))
1.0000000000084744e-150