SICPを読む(40) 2.1.4 区間算術演算
問題設定が読み取りにくかった。要するに、電気抵抗には誤差があるので「誤差を計算するシステム」を作りたい。ということらしい。とりあえず電気抵抗無視で行こう。
区間について
区間intervalってのが、想像しづらいので、RubyのRangeクラスのように表現してみる。
R1 = 1..2 R2 = 3..4
a〜bまでの区間はa..b = {x | a <= x <= b}である。
図にすると、
R1 1----2 R2 3----4
「区間」なのでaの方が常に小さい。というのが重要なポイント。
では足し算と引き算を見ていこう。
足し算
足し算は簡単。
R1 + R2 = 1..2 + 3..4 = (1 + 3) .. (2 + 4) = 4..6
普通。
引き算
演習問題の引き算が問題。
区間の引き算は、
R1 - R2 = 1..2 - 3..4 = 1..2 + -1 * 3..4 = 1..2 + -4..-3 ; upperとlowerが逆になる!! = (1 - 4) .. (2 - 3) = -3..-1
3..4にマイナスを掛けると、-3..-4とはならないので、upperとlowerは逆になり、-4..-3となる。
問題 2.7 & 2.8
そこら辺踏まえて、コーディング。
(define (make-interval a b) (cons a b)) (define (lower-bound x) (car x)) (define (upper-bound x) (cdr x)) (define (add-interval x y) (make-interval (+ (lower-bound x) (lower-bound y)) (+ (upper-bound x) (upper-bound y)))) (define (sub-interval x y) (make-interval (- (lower-bound x) (upper-bound y)) (- (upper-bound x) (lower-bound y)))) (define i-a (make-interval 1 2)) (define i-b (make-interval 3 4)) (lower-bound i-a) ; 1 (upper-bound i-a) ; 2 (add-interval i-a i-b) ; ( 4 . 6) (sub-interval i-a i-b) ; (-3 . -1)
解答みたら、(define lower-bound car)になってた。その手があったかとちょっとショックだった。