Open Source WEB

##(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")

このサイトは、 IPA の「平成15年度オープンソフトウエア活用基盤整備事業」 の委託事業として開発されたKahuaで試験的に運用しております。

Copyright (c) 2004-2007 株式会社タイムインターメディア About Us