SICP读书笔记1.1

练习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))