练习1.1
10 ;10
(+ 5 3 4) ;12
(- 9 1) ;8
(/ 6 2) ;3
(+ (* 2 4) (- 4 6)) ;6
(define a 3)
(define b (+ a 1))
(+ a b (* a b)) 19
(= a b) ;#f
(if (and (> b a) (< b (* a b)))
b
a) ; 4
(cond ((= a 4) 6)
((= b 4) (+ 6 7 a))
(else 25)) ; 16
(+ 2 (if (> b a) b a)) ;6
(* (cond ((> a b) a)
((< a b) b)
(else -1))
(+ a 1)) ;16
练习 1.2
(/ (+ 5 4 (- 2
(- 3 (+ 6
(/ 4 5)))))
(* 3
(- 6 2)
(- 2 7)))
练习1.3
需要注意考虑相等的情况,以及不能直接使用(> a b c)
这种形式
(define (sum-of-max a b c)
(cond ((and (>= a c) (>= b c)) (+ a b))
((and (>= a b) (>= c b)) (+ a c))
((and (>= b a) (>= c a)) (+ c b))))
练习 1.4
- b 大于0时
a+b
- b 小于0时
a-b
也就是a加上b的绝对值:
a + |b|
练习 1.5
- 如果使用应用序程序会进入无限递归,调用过程如下:
(test 0 (p)) ;此时对(p) 求值得到(p)
(test 0 (p)) ;继续求值(p) 程序进入无限递归
- 如果采用正则序,程序返回0,调用过程如下:
(test 0 (p))
(if (= 0 0)
0
(p))
0
练习1.6
new-if写的平方根程序会进入无限递归。
new-if 与if 最大区别在于if 特殊形式会根据条件的与否选择一个分之进行求值,并把结果当作if形式的结果。而new-if因为是普通过程,所以then-clause和else clause都会被求值。
所以用new-if写的递归程序不会终止而进入无限递归。
练习1.7
- 很小值的情况下,程序猜测到平方比既定误差小的值程序就会结束导致误差。
- 很大值的情况下,解释器精度不足以表示那么小的变化,程序进入无限循环。
改进程序使用进步比率代替固定差值,解决上述问题
(define (good-enough? old-guess new-guess)
(< (/ (abs (- old-guess new-guess))
old-guess)
0.001))
需要修改调用程序为
(define (sqrt x)
(define (average a b)
(/ (+ a b) 2))
(define (improve guess)
(average guess (/ x guess)))
(define (iter guess)
(let ((new-guess (improve guess)))
(if (good-enough? guess new-guess)
new-guess
(iter new-guess))))
(iter 1.0))
测试结果
#;222> (sqrt 2)
1.41421356237469
#;239> (sqrt 0.00009)
0.00948683304968439
#;260> (sqrt 900000000000000000000000000000000000000000000000000000000000000000000000000000000000)
9.48683298167779e+41
习题1.8
求立方根相对于求平方根只需修改改进函数即可
(define (qbrt x)
(define (improve guess)
(/ (+ (/ x (* guess guess))
(* 2 guess))
3))
(define (iter guess)
(let ((new-guess (improve guess)))
(if (good-enough? guess new-guess)
new-guess
(iter new-guess))))
(iter 1.0))