Rational
一部の値を 10 進展開で表示したい。つまり、 を表示する代わりに、 を3 % 4
表示します0.75
。この関数をタイプにしたいと思いInt -> Rational -> String
ます。1 つ目は、展開が終了しない可能性があるInt
ため、小数点以下の最大桁数を指定することです。Rational
HoogleとData.Ratio のハドックは役に立ちませんでした。この機能はどこにありますか?
Rational
一部の値を 10 進展開で表示したい。つまり、 を表示する代わりに、 を3 % 4
表示します0.75
。この関数をタイプにしたいと思いInt -> Rational -> String
ます。1 つ目は、展開が終了しない可能性があるInt
ため、小数点以下の最大桁数を指定することです。Rational
HoogleとData.Ratio のハドックは役に立ちませんでした。この機能はどこにありますか?
うまくいくよ。エレガントではありませんが、仕事はします:
import Numeric
import Data.Ratio
display :: Int -> Rational -> String
display n x = (showFFloat (Just n) $ fromRat x) ""
ライブラリ コードを再利用する任意精度バージョン:
import Data.Number.CReal
display :: Int -> Rational -> String
display digits num = showCReal digits (fromRational num)
以前、有理数を検査しやすい方法で数字に変換する関数を見たことがあることは知っています (つまり、数字が繰り返される場所が明確になります) が、今は見つけられないようです。いずれにせよ、それが必要であることが判明した場合、書くのは難しくありません。通常の長除算アルゴリズムをコード化し、既に行った除算を監視するだけです。
import Data.List as L
import Data.Ratio
display :: (Integral i, Show i) => Int -> Ratio i -> String
display len rat = (if num < 0 then "-" else "") ++ show ip ++ "." ++ L.take len (go (abs num - ip * den))
where
num = numerator rat
den = denominator rat
ip = abs num `quot` den
go 0 = ""
go x = shows d (go next)
where
(d, next) = (10 * x) `quotRem` den