mathclojurerational-numbersinexact-arithmetic

How to convert any number to a clojure.lang.Ratio type in Clojure?


In Scheme I can do:

#;> (numerator 1/3)
1
#;> (denominator 1/3)
3

In Clojure I can do something similar:

user=> (numerator 1/3)
1
user=> (denominator 1/3)
3

But in Scheme I can do:

#;> (numerator 0.3)
3.0

and it is not possible in Clojure:

user=> (numerator 0.3)

ClassCastException java.lang.Double cannot be cast to clojure.lang.Ratio  clojure.core/numerator (core.clj:3306)

How can I convert a Double (or actually any kind of number) into a clojure.lang.Ratio?

In Scheme we have also inexact->exact what would be something like "double to ratio" in Clojure, but I can't find anything similar to it.


Solution

  • Ooh, I know this one!

    user=> (rationalize 0.3)
    3/10
    user=> (numerator (rationalize 0.3))
    3
    

    But the OP points out that this doesn't work for all numbers:

    user=> (numerator (rationalize 1))
    ClassCastException java.lang.Long cannot be cast to clojure.lang.Ratio  clojure.core/numerator (core.clj:3306)
    

    see his Java interop workaround in his answer.


    [edit] OP here:

    Here is a more generic solution:

    user=> (numerator (clojure.lang.Numbers/toRatio (rationalize 1)))
    1
    user=> (numerator (clojure.lang.Numbers/toRatio (rationalize 0.3)))
    3
    user=> (numerator (clojure.lang.Numbers/toRatio (rationalize 1/3)))
    1