# Clojure Ratios

Computers do math really quickly. Yet, computers struggle with all kinds of things with math. Take, for example, the simple fraction: 2/3. This should be easy to store right? In most languages, it isn’t.

We’re going to use 2/3 throughout all our examples. We’ll use the literal `2/3` instead of `(/ 2 3)` because it’s more compact, and is equivalent:

```clojure
(= 2/3 (/ 2 3))
;;=> true

2/3
;;=> 2/3
```

If you’ve programmed in most languages, you probably expected output like `0.6666667`. In Clojure, we need to force that with a cast:

```clojure
(float 2/3)
;;=> 0.6666667
```

After casting, we can see they’re not equal:

```clojure
(= 2/3 (float 2/3))
;;=> false
```

So, what was that `2/3` we saw? Let’s inspect its type, and its value. I don’t want to write that more than once, so here’s a cool little helper function:

```clojure
(defn value-and-type
  [& args]
  (map (juxt identity type) args))
```

Here it is in action:

```clojure
(value-and-type 2/3 (float 2/3))
;;=> ([2/3 clojure.lang.Ratio]
;;    [0.6666667 java.lang.Float])
```

Aha! The `2/3` is a special Clojure `Ratio` type. What can we do with a `Ratio`?

Determine whether a value is one:

```clojure
(ratio? 2/3)
;;=> true

(ratio? 3/3)
;;=> false
```

Note that `rational?` is a little more inclusive:

```clojure
(rational? 3/3)
;;=> true
```

Inspect its numerator and denominator:

```clojure
(numerator 2/3)
;;=> 2

(denominator 2/3)
;;=> 3
```

Do math operations without losing precision:

```clojure
(value-and-type
 (* 2/3 3)
 (* (float 2/3) 3))
;;=> ([2N clojure.lang.BigInt]
;;    [2.0000000596046448 java.lang.Double])
```

That is pretty great!

You can attempt to turn a floating point number into a ratio. Beware!

```clojure
(value-and-type
 (rationalize 2/3)
 (rationalize (float 2/3)))
;;=> ([2/3 clojure.lang.Ratio]
;;    [416666679084301/625000000000000
;;     clojure.lang.Ratio])
```

You may have guessed the following would fare better because our computers are binary, and you’d be right:

```clojure
(value-and-type
 (rationalize (float 1/2))
 (rationalize (float 3/2)))
;;=> ([1/2 clojure.lang.Ratio]
;;    [3/2 clojure.lang.Ratio])
```

However, for even `2/3`, `BigInt` can save the day!

```clojure
(value-and-type
 (rationalize (/ 2N 3N)))
;;=> ([2/3 clojure.lang.Ratio])
```
