[SICP 2.1.4] Exercise 2.11 Memo
5-30-2014
Exercise 2.11: Rewrite procedure mul-interval using Ben’s suggestion.
The default mul-interval executes 4 multiplications on every case of operations, because the process calculates p1 to p4 regardless of the signs of the endpoints.
So, the objective of this problem is to minimize the number of operations.
(define (mul-interval x y) (let ((mi make-interval) (lx (lower-bound x)) (ux (upper-bound x)) (ly (lower-bound y)) (uy (upper-bound y))) (cond ((and (neg-int? x) (neg-int? y)) (mi (* lx ly) (* ux uy))) ((and (neg-int? x) (zero-span? y)) (mi (* lx uy) (* lx ly))) ((and (neg-int? x) (pos-int? y)) (mi (* ux uy) (* lx ly))) ((and (zero-span? x) (neg-int? y)) (mi (* ux uy) (* lx uy))) ((and (zero-span? x) (pos-int? y)) (mi (* lx uy) (* ux uy))) ((and (pos-int? x) (neg-int? y)) (mi (* ux uy) (* lx ly))) ((and (pos-int? x) (zero-span? y)) (mi (* ux ly) (* ux uy))) ((and (pos-int? x) (pos-int? y)) (mi (* lx ly) (* ux uy))) ((and (zero-span? x) (zero-span? y)) (mi (min (* lx uy) (* ux ly)) (max (* lx ly) (* ux uy))))))) (define i1 (make-interval -5 3)) (define i2 (make-interval -2 110)) (mul-interval i1 i2) ; (-550, 330)
Note that there will be no point to rewrite the procedure if you write the multiplication as the variable defined in the `let`, because variables we define in `let` are all executed whether or not we use them. In this case, if you write as follows, 4 multiplications are executed in mul-interval every time:
(define (mul-interval x y) (let ((mi make-interval) (lxly (* (lower-bound x) (lower-bound y))) (lxuy (* (lower-bound x) (upper-bound y))) (uxly (* (upper-bound x) (lower-bound y))) (uxuy (* (upper-bound x) (upper-bound y)))) : : :
If you want to confirm this kind of behavior of `let`, try defining (zero-div (/ 1 0)) as an variable of `let`, and you’ll soon get zero-division error even if you aren’t using variable zero-div in the process.