問題1.6~問題1.8
問題1.6
(if ⟨predicate⟩ ⟨consequent⟩ ⟨alternative⟩)
において、predicateが真ならばconsequentを評価し、predicateが偽ならばalternativeを評価する。
つまり、consequentとalternativeは必ずどちらか片方しか評価されない。
しかしnew-ifの場合、consequentもalternativeも必ず評価を行う。
このときalternativeは
(sqrt-iter (improve guess x) x)
のsqrt-iterの再帰となっているため、sqrtは無限ループとなってしまう。
処理系により結果が異なるという実例を目の当たりにして感動!
問題1.7
下の例のように平方根を求める対象の数が0.001より小さい場合は、good-enough?において適切に判定が行われない。
> (square (sqrt 0.0002)) 0.0011124103413204282
good-enough?を以下のように改良するとうまくいく。
> (define (good-enough? guess x) (< (/ (square guess) x) 1.001) ) > (square (sqrt 0.0002)) 0.0002000004105964592
大きい数の場合、有効数字の範囲内での改良が判定基準を満たさないため、無限ループになってしまうらしい。
問題1.8
improve guess x の手続きを修正する。
> (define (curt x) (curt-iter 1.0 x)) > (define (curt-iter guess x) (if (good-enough? guess x) guess (curt-iter (improve guess x) x))) > (define (good-enough? guess x) (< (abs (- (cube guess) x)) 0.001)) > (define (improve guess x) (/ (+ (/ x (square guess)) (* 2 guess)) 3)) > (define (cube x) (* x x x)) > (define (square x) (* x x))
動作確認
> (curt 4) 1.5874096961416333 > (cube 1.587) 3.996969003