SICP 연습문제 2.10 친절한 풀이

문제

전문 시스템 프로그래머 Ben Bitdiddle는 Alyssa가 한 일을 어깨 너머로 보다가, 0이 들어 있는 구간 값으로 나누어야 할 때 무슨 일을 하는지 깨끗하게 드러나지 않는다고 했다. 구간에 0이 들어 있는지 따져서 문제가 생겼을 때 잘못되었다고 알려줄 수 있도록, Alyssa의 코드를 고쳐 보아라.

문제로 부터 얻은 것

error를 써서 요류처리를 하는 방법을 배웠습니다.

문제풀이

우선 구간 안에 0이 포함되는지 감별하는 프로시저부터 만들어 보겠습니다.
구간 안에 0이 포함되려면 아래의 경우 중 하나를 만족해야 합니다.

  1. 하한값이 음수이면서 상한값이 양수이다.
  2. 상한값이 0이다.
  3. 하한값이 0이다.



위의 조건에 따라 프로시저를 구성하면 아래와 같습니다.

(define (pos? x)
(or (> x 0) (= x 0)))

(define (neg? x)
(< x 0))

(define (contain-zero? z)
(cond ((and (neg? (lower-bound z))
(pos? (upper-bound z)))
#t)
((or (= (lower-bound z) 0)
(= (upper-bound z) 0))
#t)
(else #f)))



나눗셈에서 0이 포함된 구간을 어떤 수로 나누는 것은 크게 오류를 발생시키지 않습니다.
하지만 0이 포함된 구간으로 나누는 것은 예상치 못한 오류를 발생시킵니다.
예를들어 (1,3)(1,3)인 구간을 (2,1)(-2,1)로 나누는 상황을 가정해 봅시다.
상한값과 하한값을 구할 수 있습니까?
상한값과 하한값은 -∞입니다.
3을 0에 무한히 가까운 양수로 나눈 것과 0에 무한히 가까운 음수로 나는 값이기 때문입니다.
이처럼 예상치 못한 범위가 출력될 수 있습니다.
그렇기 때문에 코드에 에러 메세지를 넣어서 계산을 종료시키도록 프로시저를 수정하겠습니다.

(define (div-interval x y)
(if (contain-zero? y)
(error "second argument contains 0 in range"))
(mul-interval x
(make-interval (/ 1.0 (upper-bound y))
(/ 1.0 (lower-bound y)))))



범위에 0이 포함되어 있을때 에러를 발생시키는 모습



읽어주셔서 감사합니다.