Search code examples
haskelldoublerational-number

problem with Double and Rational Number


I am writing a function in which I need to read a string contains floating point number and turn it back to Rational. But When I do toRational (read input :: Double), it will not turn for eg: 0.9 into 9 % 10 as expected, but instead 81..... % 9007... Thx


Solution

  • This is correct behavior. The number 0.9 is not representable as a Double, not in Haskell, C, or Java. This is because Double and Float use base 2: they can only represent a certain subset of the dyadic fractions exactly.

    To get the behavior you want, import the Numeric module and use the readFloat function. The interface is fairly wonky (it uses the ReadS type), so you'll have to wrap it a little. Here's how you can use it:

    import Numeric
    myReadFloat :: String -> Rational -- type signature is necessary here
    myReadFloat str =
        case readFloat str of
          ((n, []):_) -> n
          _ -> error "Invalid number"
    

    And, the result:

    > myReadFloat "0.9"
    9 % 10