#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.