1.6
(define (new-if pre then-clause else-clause)
(cond (pre then-clause)
(else else-clause)))
(define (sqrt-iter guess target)
(new-if (good-enough? guess target)
guess
(sqrt-iter (improve guess target) target)))
(define (improve guess target)
(average guess (/ target guess)))
(define (average x y)
(/ (+ x y) 2))
(define (good-enough? guess target)
(< (abs (- (square guess) target)) 0.01))
(define (sqrt x)
(sqrt-iter 1.0 x))
这道题目就是因为每次使用new-if的时候,因为是应用序,所以所有的参数都必须首先计算出来,而new-if的第三个参数是一个递归。因此会调用这个递归,又因为这个歌递归有是一个递归,因此产生的
无限循环,这儿的问题就是递归每次都在进行,但是分支并没有发生。
输出:
#|kawa:1|# (define (sqrt x)
#|(---:2|# (sqrt-iter 1.0 x))
/dev/stdin:2:2: warning - no declaration seen for sqrt-iter
#|kawa:3|# (define (good-enough? guess target)
#|(---:4|# (< (abs (- (square guess) target)) 0.01))
#|kawa:5|# (define (average x y)
#|(---:6|# (/ (+ x y) 2))
#|kawa:7|# 2
2
#|kawa:8|# (define (improve guess target)
#|(---:9|# (average guess (/ target guess)))
#|kawa:10|# 2
2
#|kawa:11|# (define (new-if pre then-clause else-clause)
#|(---:12|# (cond (pre then-clause)
#|(---:13|# (else else-clause)))
#|kawa:14|# 2
2
#|kawa:15|# (define (sqrt-iter guess target)
#|(---:16|# (new-if (good-enough? guess target)
#|(---:17|# guess
#|(---:18|# (sqrt-iter (improve guess target) target)))
/dev/stdin:16:2: warning - unreachable procedure call
/dev/stdin:18:3: note - this operand never finish()es
#|kawa:19|# 2
2
#|kawa:20|# (new_if #t 10 1)
/dev/stdin:20:1: warning - no declaration seen for new_if
/dev/stdin:20:1: unbound location new_if
at gnu.mapping.SharedLocation.get(SharedLocation.java:22)
at gnu.mapping.ThreadLocation.get(ThreadLocation.java:105)
at atInteractiveLevel$11.run(stdin:20)
at gnu.expr.ModuleExp.evalModule2(ModuleExp.java:309)
at gnu.expr.ModuleExp.evalModule(ModuleExp.java:210)
at kawa.Shell.run(Shell.java:279)
at kawa.Shell.run(Shell.java:194)
at kawa.Shell.run(Shell.java:175)
at kawa.ReplDocument$2.apply0(ReplDocument.java:97)
at gnu.mapping.RunnableClosure.run(RunnableClosure.java:78)
at gnu.mapping.Future.run(Future.java:44)
#|kawa:21|# (new-if #t 10 1)
10
#|kawa:22|# (define (sqrt-iter guess target)
#|(---:23|# (new-if (good-enough? guess target)
#|(---:24|# guess
#|(---:25|# (sqrt-iter (improve guess target) target)))
/dev/stdin:23:2: warning - unreachable procedure call
/dev/stdin:25:3: note - this operand never finishes
#|kawa:26|# (define (sqrt x)
#|(---:27|# (sqrt-iter 1.0 x))
#|kawa:28|# (sqrt 4)
...(嘿嘿,又卡死)
1.7,这个问题就是确定精度的问题,对于一个很小的数来说精度必须足够小,对于一个较大的数来说精度又应该方法。重要的是,人无法精确控制这个过程。这个就是改变一下good-enough?函数了。
(define (average x y)
(/ (+ x y) 2))
(define (improve guess target)
(average guess (/ target guess)))
(define (good-enough? guess target)
(< (abs (- (square guess) target)) (/ target guess guess 1000)))
(define (sqrt-iter guess target)
(if (good-enough? guess target)
guess
(sqrt-iter (improve guess target) target)))
(define (sqrt x)
(sqrt-iter 1.0 x))
1.8 这个题目类似于求平方,只是需要改变一些参数。
(define (average-by-three x y)
(/ (+ x y) 3))
(define (pow target n)
(if (= n 0) 1 (* (pow target (- n 1)) target)))
(define (improve y x)
(average-by-three (* 2 y) (/ x (pow y 2))))
(define (good-enough? y x)
(< (abs (- (pow y 3) x)) 0.01))
(define (cube-iter y x)
(if (good-enough? y x)
y
(cube-iter (improve y x) x)))
(define (cube x)
(cube-iter (/ x 2) x))