# sicp-ex-2.1

```
;; ex 2.1

(define (numer x) (car x))

(define (denom x) (cdr x))

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

(define (make-rat n d)
(let ((g ((if (< d 0) - +) (gcd n d))))
(cons (/ n g) (/ d g))))

;; Testing
(print-rat (make-rat 6 9)) ; 2/3
(print-rat (make-rat -6 9)) ; -2/3
(print-rat (make-rat 6 -9)) ; -2/3
(print-rat (make-rat -6 -9)) ; 2/3

```

There is a bug in the solution above. If gcd is defined as described in 1.2.5, it will have sign depending on the number of iterations it runs and the signs of a and b. For example:

```(gcd 1 -2) ; 1
(gcd 6 -9) ; -3
```

Thus:

```(print-rat (make-rat 1 -2)) ; 1/-2
(print-rat (make-rat 6 -9)) ; -2/3
```

To fix either make gcd return an absolute value or get the absolute value in make-rat (this is implemented below):

```(define (make-rat n d)
(let ((g ((if (< d 0) - +) (abs (gcd n d)))))
(cons (/ n g) (/ d g))))
```

If we don't want to consider the sign of gcd, and still get the right answer, we could implement the following:

```(define (make-rat n d)
(define g (gcd n d))
(cond ((> (* n d) 0) (cons (abs (/ n g)) (abs (/ d g))))
((< (* n d) 0) (cons (- (abs (/ n g))) (abs (/ d g))))))
```

Lily X. :)

We could save the simplified numbers as variables to make the program more readable too

``` (define (make-rat n d)
(define g (gcd n d))
(let        ((simple-n (abs (/ n g)))
(simple-d (abs (/ d g))))
(cond
((> (* n d) 0) (cons simple-n simple-d))
((< (* n d) 0) (cons (- simple-n) simple-d)))))
```

Another solution follows:

``` (define (make-rat n d)
(define (sign x) (if (< x 0) - +))
(let ((g (gcd n d)))
(cons ((sign d) (/ n g))
(abs (/ d g)))))
```

Evan

Here's a solution that doesn't use conditionals.

``` (define (make-rat n d)
(let ((g (abs (gcd n d)))
(abs-d (abs d)))
(cons (/ (* n (/ d abs-d)) g)
(/ abs-d g))))
```

Let g take the absolute value of the gcd expression, so its sign won't interfere with the final sign of n and d.

Then, when you give cons, as its first argument, the multiplication of n by (/ d abs-d), you get the following:

• Numerator becomes negative if it was originally positive AND D is negative;
• Numerator remains negative if it was originally negative AND D is positive;
• Numerator remains positive if it was originally positive AND D is also positive;
• Numerator becomes positive if it was originally negative AND D is also negative;

Giving abs-d to cons as its second argument removes the possible sign from the denominator.

I really don't see why all the solutions here should look as cluttered as they do.

We just define sign as

``` (define (bool->number x)
(cond ((equal? x #t) 1)
((equal? x #f) 0)
(else "Input must be a boolean!")
)
)

(define (sign x)
(- (bool->number (> x 0))
(bool->number (< x 0))
)
)
```

And then make-rat as

``` (define (make-rat n d)
(if (= d 0) (error "The denonimator must not be zero!"))

(define (rat-change x)
(/ (* x (sign d)) (gcd n d))
)

(cons (rat-change n) (rat-change d ))
)
```