# sicp-ex-2.13

jz

No scheme, just math. If Ca is center of a, and Ta is tolerance of a, a is the interval

```  a = [Ca*(1 - 0.5*Ta), Ca*(1 + 0.5*Ta)]
```

and b is

```  b = [Cb*(1 - 0.5*Tb), Cb*(1 + 0.5*Tb)]
```

If the endpoints are positive, a*b has the endpoints (after simplifying):

```  a*b = [Ca*Cb*(1 - 0.5*(Ta + Tb) + 0.25*Ta*Tb),
Ca*Cb*(1 + 0.5*(Ta + Tb) + 0.25*Ta*Tb)]
```

Ta*Tb will be a wee number, so it can be ignored. So, it appears that for small tolerances, the tolerance of the product will be approximately the sum of the component tolerances.

A quick check:

```
(define (make-interval a b) (cons a b))
(define (upper-bound interval) (max (car interval) (cdr interval)))
(define (lower-bound interval) (min (car interval) (cdr interval)))
(define (center i) (/ (+ (upper-bound i) (lower-bound i)) 2))

;; Percent is between 0 and 100.0
(define (make-interval-center-percent c pct)
(let ((width (* c (/ pct 100.0))))
(make-interval (- c width) (+ c width))))

(define (percent-tolerance i)
(let ((center (/ (+ (upper-bound i) (lower-bound i)) 2.0))
(width (/ (- (upper-bound i) (lower-bound i)) 2.0)))
(* (/ width center) 100)))

(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 i (make-interval-center-percent 10 0.5))
(define j (make-interval-center-percent 10 0.4))
(percent-tolerance (mul-interval i j))

;; Gives 0.89998, pretty close to (0.5 + 0.4).

```

sTeven

My method:

```  percent-interval :=> PI  old-interval :=> OI
```
```  PI(a, p1) -> OI(a-a*p1, a+a*p1)
PI(b, p2) -> OI(b-b*p2, b+b*p2)
```
```  PI(c, p) = PI(a, p1)*PI(b, p2)
:=> OI(a-a*p1, a+a*p1) * OI(b-b*p2, b+b*p2)
= OI((a-a*p1)*(b-b*p2), (a+a*p1)*(b+b*p2))
= OI(cL, cU)
c = (cL + cU)/2
= ((a-a*p1)*(b-b*p2) + (a+a*p1)*(b+b*p2))/2
= a*b*(1+p1*p2)
p = (c-cL)/c
= (a*b*(1+p1*p2) - (a-a*p1)*(b-b*p2))/a*b*(1+p1*p2)
= a*b*(p1 + p2)/a*b*(1+p1*p2)
= (p1+p2)/(1+p1*p2)
```
```  c = a*b*(1+p1*p2);
p = (p1+p2)/(1+p1*p2);
```

Example:

```  PI(10, 0.005)*PI(10, 0.004)
= PI(10*10*(1+0.004*0.005), (0.004+0.005)/(1+0.004*0.005))
= PI(100.002, 0.00899982);
```