SICP exercise 2.01

From Drewiki

Jump to: navigation, search

Problem

Define a better version of make-rat (from chapter 2.1.1 of the text) that handles both positive and negative arguments. make-rat should normalize the sign so that if the rational number is positive, both the numerator and denominator are positive, and if the rational number is negative, only the numerator is negative.

Solution

Using the gcd procedure from exercise 1.20, here's a version of make-rat that handles negative numbers:

(define (gcd a b)
  (if (= b 0)
      a
      (gcd b (remainder a b))))
 
(define (make-rat n d)
  (define (maker x y g)
    (cons (/ x g) (/ y g)))
  (let ((g (gcd (abs n) (abs d))))
    (cond ((and (< n 0) (< d 0)) (maker (abs n) (abs d) g))
          ((< d 0) (maker (- n) (abs d) g))
          (else (maker n d g)))))
 
(define (numer x) (car x))
 
(define (denom x) (cdr x))
 
(define (print-rat x)
  (newline)
  (display (numer x))
  (display "/")
  (display (denom x))
  (newline))

Tests:

(print-rat (make-rat 1 3))

Output:

1/3
(print-rat (make-rat -1 3))

Output:

-1/3
(print-rat (make-rat -1 -3))

Output:

1/3
(print-rat (make-rat 1 -3))

Output:

-1/3
(print-rat (make-rat 4 6))

Output:

2/3
(print-rat (make-rat -4 6))

Output:

-2/3
(print-rat (make-rat -4 -6))

Output:

2/3
(print-rat (make-rat 4 -6))

Output:

-2/3
Personal tools