(load "2.7.txt") ; For make-interval, upper-bound, and lower-bound ; This file with overwrite mul-interval ; 3 cases for an interval ; - interval is all negative ; - interval is all positive ; - interval includes 0 ; => 9 possible cases for a pair of intervals ; all cases require only 2 multiplications except case of two intervals ; spanning 0 which require 4 multiplications. (define (mul-interval x y) (let ((xl (lower-bound x)) (xu (upper-bound x)) (yl (lower-bound y)) (yu (upper-bound y))) (cond ((< xu 0) (cond ((< yu 0) ; negative * negative (make-interval (* xu yu) (* xl yl))) ((> yl 0) ; negative * positive (make-interval (* xl yu) (* xu yl))) (else ; negative * mixed (make-interval (* xl yu) (* xl yl))))) ((> xl 0) (cond ((< yu 0) ; positive * negative (make-interval (* xu yl) (* xl yu))) ((> yl 0) ; positive * positive (make-interval (* xl yl) (* xu yu))) (else ; positive * mixed (make-interval (* xu yl) (* xu yu))))) (else (cond ((< yu 0) ; mixed * negative (make-interval (* xu yl) (* xl yl))) ((> yl 0) ; mixed * positive (make-interval (* xl yu) (* xu yu))) (else ; mixed * mixed (make-interval (min (* xl yu) (* xu yl)) (max (* xl yl) (* xu yu))))))))) (define (test-mul-interval) (define (test test-case) (let ((x (make-interval (caar test-case) (cadar test-case))) (y (make-interval (caadr test-case) (cadadr test-case))) (expected (make-interval (caaddr test-case) (car (cdaddr test-case))))) (let ((got (mul-interval x y))) (cond ((equal? got expected) #t) (else (error "failed" x y expected got)))))) (let ((test-cases '( ((-2 -1) (-4 -3) (3 8)) ((-2 -1) (3 4) (-8 -3)) ((-2 -1) (-3 4) (-8 6)) ((-2 -1) (0 4) (-8 0)) ((-2 -1) (-3 0) (0 6)) ((-3 4) (-2 -1) (-8 6)) ; Upper bound ; xl * yl > xu * yu ((-3 4) (-2 1) (-8 6)) ; xl * yl < xu * yu ((-3 4) (-1 2) (-6 8)) ; Lower bound ; xl * yu < xu * yl ((-3 4) (-1 2) (-6 8)) ; xl * yu > xu * yl ((-3 4) (-2 1) (-8 6)) ((1 2) (-4 -3) (-8 -3)) ((1 2) (3 4) (3 8)) ((1 2) (-3 4) (-6 8)) ((1 2) (0 4) (0 8)) ((1 2) (-3 0) (-6 0))))) (map test test-cases)))