欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

SICP 2.7~2.16习题答案

程序员文章站 2022-07-14 10:55:01
...
这一段的题目有点多,都是要有前面的代码的,写到一起得了

2.13用代数式看一下就知道了,比较容易。
2.14用代码试试看就知道了,感觉操作会引起误差,但不知道为什么,2.15,2.16同样
但是通过2.14的结果就知道,2.15的结论应该是对的,除法运算并没有引入新的误差。

2.2节开始进入令人愉快的数据结构了,^_^。令人期待。

(define (make-interval a b) (cons a b))

;; 2.7
(define (lower-bound n) (car n))
(define (upper-bound n) (cdr n))

(define (width-interval i)
  (/ (- (upper-bound i) (lower-bound i)) 2))

(define (add-interval x y)
  (make-interval (+ (lower-bound x) (lower-bound y))
                 (+ (upper-bound x) (upper-bound y))))

;;(define (mul-interval x y)
;;  (let ((p1 (* (lower-bound x) (lower-bound y)))
;;        (p2 (* (lower-bound x) (upper-bound y)))
;;        (p3 (* (upper-bound x) (lower-bound y)))
;;        (p4 (* (upper-bound x) (upper-bound y))))
;;    (make-interval (min p1 p2 p3 p4)
;;                   (max p1 p2 p3 p4))))

;; 2.11
(define (mul-interval x y)
  (let ((x-l (lower-bound x))
        (x-u (upper-bound x))
        (y-l (lower-bound y))
        (y-u (upper-bound y)))
    (cond ((and (> 0 x-l) (> 0 x-u)) (cond ((and (> 0 y-l) (> 0 y-u)) (make-interval (* x-l y-l) (* x-u y-u)))
                                           ((and (> 0 y-l) (< 0 y-u)) (make-interval (* x-l y-u) (* x-l y-l)))
                                           ((and (< 0 y-l) (< 0 y-u)) (make-interval (* x-l y-u) (* x-u y-l)))))
          ((and (> 0 x-l) (< 0 x-u)) (cond ((and (> 0 y-l) (> 0 y-u)) (make-interval (* x-u y-l) (* x-l y-l)))
                                           ((and (> 0 y-l) (< 0 y-u)) (make-interval (* x-l y-u) (* x-u y-u)))
                                           ((and (< 0 y-l) (< 0 y-u)) (make-interval (* x-l y-u) (* x-u y-u)))))
          ((and (< 0 x-l) (< 0 x-u)) (cond ((and (> 0 y-l) (> 0 y-u)) (make-interval (* x-u y-l) (* x-l y-u)))
                                           ((and (> 0 y-l) (< 0 y-u)) (make-interval (* x-l y-u) (* x-u y-u)))
                                           ((and (< 0 y-l) (< 0 y-u)) (make-interval (* x-l y-l) (* x-u y-u))))))))

(define (div-interval x y)
  ;; 2.10
  (if (> 0 (* (upper-bound y) (lower-bound y)))
      (error "divisor interval should be above 0")
      (mul-interval x
                    (make-interval (/ 1.0 (upper-bound y))
                                   (/ 1.0 (lower-bound y))))))

;; 2.12
(define (make-center-width c w)
  (make-interval (- c w) (+ c w)))

(define (make-center-percent center percent)
  (let ((width (* center ( / percent 100.0))))
    (make-center-width center width)))
 
(define (percent i)
  (* (/ (interval-width i) (center i)) 100.0))

;; 2.8
(define (sub-interval a b)
  (make-interval (- (lower-bound a) (upper-bound b))
                 (- (upper-bound a) (lower-bound b))))

(define (par1 r1 r2)
  (div-interval (mul-interval r1 r2)
                (add-interval r1 r2)))

(define (par2 r1 r2)
  (let ((one (make-interval 1 1)))
    (div-interval one
                  (add-interval (div-interval one r1)
                                (div-interval one r2)))))