正と負の両方の引数を扱うことができる改良版 make-rat を定義せよ。
make-rat は符号を正規化し、正の有理数であれば分子と分母の両方が正となり、負の有理数であれば分子のみが負になるようにする。
改良前の make-rat
はこちら。
(define (make-rat n d)
(let ((g (gcd n d)))
(cons (/ n g) (/ d g))))
n
と d
両方負の数だったら正の数、どちらか片方が負の数だったら負の数にするのだと思う。とりあえず愚直に書いてみる。
(define (make-rat n d)
(let ((g (gcd n d)))
(cond
((and (> n 0) (> d 0)) (cons (/ n g) (/ d g)))
((and (< n 0) (< d 0)) (cons (/ n g) (/ d g)))
((and (> n 0) (< d 0)) (cons (- (/ n g)) (- (/ d g))))
((and (< n 0) (> d 0)) (cons (- (/ n g)) (- (/ d g)))))))
[両方正or負]のグループと[片方正で片方負]のグループで返すものがそれぞれ一緒なので、まとめる。
(define (make-rat n d)
(let ((g (gcd n d)))
(cond
((or (and (> n 0) (< d 0)) (and (< n 0) (> d 0)))
(cons (- (/ n g)) (- (/ d g))))
(else
(cons (/ n g) (/ d g))))))
合ってるのかな・・・
(define (make-rat n d)
(let ((g (abs (gcd n d))))
(if (< d 0)
(cons (/ (- n) g) (/ (- d) g))
(cons (/ n g) (/ d g)))))
なるほど、確かに・・・