Chat (Lingr.com)
Informaiton
Daily
Column
- MySQL日本語の旅(5/1)
- アクセス向上秘伝(5/9)
- 一風変ったHaskellλ門(6/13)
- SICP Answer Book (5/31) 問題3.26追加
Zope Solution
Extra
アーカイブ
OSS案内所
Site Info
関連リンク
##(link2sicp "book-Z-H-10.html#%_thm_1.7" "Exercise 1.7")
解答例
小さな数の場合
xの値が判定基準値(この場合 1.0E-3)に比してずっと小さい場合、 たとえば、x = 1.0E-6 であるような場合、理想的には、 (sqrt x) --> 1.0E-3 であるが guess の自乗が基準判定値より小さくなった時点で (good-enough? guess x) が真 となるため、十分な推定値の改良がおこなわれずに終了してしまう。
gosh> (sqrt 1.0E-6) 0.031260655525445276 gosh> (square (sqrt 1.0E-6)) 9.772285838805523e-4 gosh>
大きな数の場合
improve による推定値の改良は、一般的には有効数字の範囲内であるため、 大きな数の場合、有効数字の範囲内での改良が、判定基準値を満すさず、 無限ループになってしまう。
gosh> (sqrt 1.0E29) ;; 無限ループ
改良版
(define (sqrt-iter old new x)
(if (good-enough? old new)
new
(sqrt-iter new (improve new x) x)))
(define (good-enough? old new)
(< (abs (- 1.0 (/ old new))) 0.001))
(define (sqrt x)
(sqrt-iter 1.0 x x))
計算結果
gosh> (sqrt 1.0E-6) 0.0010000001533016628 gosh> (square (sqrt 1.0E-6)) 1.0000003066033492e-6 gosh> (sqrt 1.0E29) 3.162277660171076e14 gosh> (square (sqrt 1.0E29)) 1.0000000000017057e29
改良版は小さい値に対しても、大きい値に対しても期待通り動作する。
コード
##(sicp-answer-code "ex-1.7.scm")