sicp-solutions/chapter-2/ex-2.14.scm

72 lines
No EOL
2.1 KiB
Scheme

#lang sicp
(define make-interval cons)
(define (lower-bound i)
(car i))
(define (upper-bound i)
(cdr i))
(define (sub-interval a b)
(make-interval (- (lower-bound a)
(upper-bound b))
(- (upper-bound a)
(lower-bound b))))
(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))))
(define (add-interval x y)
(make-interval (+ (lower-bound x) (lower-bound y))
(+ (upper-bound x) (upper-bound y))))
(define (div-interval x y)
(if (<= (* (lower-bound y) (upper-bound y)) 0)
(error "division by zero")
(mul-interval
x
(make-interval (/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y))))))
(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)))))
(define example-1 (make-interval 1 2))
(define example-2 (make-interval 0.999 1.001))
(div-interval example-1 example-1)
;(0.5 . 2.0)
(div-interval example-2 example-2)
;(0.9980019980019982 . 1.002002002002002)
; It's simplest to explain this using the previous result
; that the tolerance of a product of a*b, is roughly the
; sum of the tolerances (if the tolerances are small
; relative to the center point)
; We can also derive that the tolerance of 1/a is equal to
; the tolerance of a.
; Proof:
; a = [x-w,x+w], t_a = w/x
; 1/a = [1/(x+w), 1/(x-w)] =
; [(1/(x+w)) * (x-w)/(x-w), (1/(x-w)) * (x+w)/(x+w)] =
; [(x-w)/(x^2-w^2), (x+w)/(x^2-w^2)] =
; x/(x^2-w^2) +- w/(x^2-w^2)
; the tolerance of the product is then:
; (w/(x^2-w^2)) / (x/(x^2-w^2)) = w/x, same as t_a.
;
; This means, using the previous approximation, that the
; expression a/a = 1, rather than having a tolerance of 0
; is going to have a tolerance doubling that of a.