I want to display some Rational
values in their decimal expansion. That is, instead of displaying 3 % 4
, I would rather display 0.75
. I'd like this function to be of type Int -> Rational -> String
. The first Int
is to specify the maximum number of decimal places, since Rational
expansions may be non-terminating.
Hoogle and the haddocks for Data.Ratio didn't help me. Where can I find this function?
You can make it. Not elegant, but does the job:
import Numeric
import Data.Ratio
display :: Int -> Rational -> String
display n x = (showFFloat (Just n) $ fromRat x) ""
Here is an arbitrary precision solution that doesn't use floats:
import Data.Ratio
display :: Int -> Rational -> String
display len rat = (if num < 0 then "-" else "") ++ (shows d ("." ++ take len (go next)))
where
(d, next) = abs num `quotRem` den
num = numerator rat
den = denominator rat
go 0 = ""
go x = let (d, next) = (10 * x) `quotRem` den
in shows d (go next)
Arbitrary precision version that re-uses library code:
import Data.Number.CReal
display :: Int -> Rational -> String
display digits num = showCReal digits (fromRational num)
I know I've seen a function before that converts rationals into digits in a way that's easier to inspect (i.e. that makes it quite clear where the digits start repeating), but I can't seem to find it now. In any case, it's not hard to write, if that turns out to be a need; you just code up the usual long-division algorithm and watch for divisions you've already done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With