理系学生日記

おまえはいつまで学生気分なのか

問題2-1

2章はデータの抽象がテーマ.
まずは有理数をデータとして表して、符号を正規化できる有理数構築関数make-ratを定義する。

(define (add-rat x y)
  (make-rat (+ (* (numer x) (denom y))
	       (* (numer y) (denom x)))
	    (* (denom x) (denom y))))

(define (sub-rat x y)
  (make-rat (- (* (numer x) (denom y))
	       (* (numer y) (denom x)))
	    (* (denom x) (denom y))))

(define (mul-rat x y)
  (make-rat (* (numer x) (numer y))
	    (* (denom x) (denom y))))

(define (div-rat x y)
  (make-rat (* (numer x) (denom y))
	    (* (denom x) (numer y))))

(define (equal-rat? x y)
  (= (* (numer x) (denom y))
     (* (numer y) (denom x))))

(define (make-rat n d)
  (let ((g (gcd n d))
	(sign (if (or (and (positive? n) (positive? d))
		      (and (negative? n) (negative? n)))
		  1
		  -1)))
    (cons (* sign (/ n g)) (/ d g))))

(define (numer x) (car x))

(define (denom x) (cdr x))

(define (print-rat x)
  (newline)
  (display (numer x))
  (display "/")
  (display (denom x)))

負の数同士の乗算でテスト:-(1/3)*-(1/2)

gosh> (define m-one-third (make-rat -1 3))
m-one-third
gosh> (define m-one-half (make-rat -1 2))
m-one-half
gosh> (print-rat (mul-rat m-one-third m-one-half))

1/6#<undef>