我一直参与a programming contest和one of the problems'输入数据,其中包含十进制格式的小数:0.75
就是一个例子。
将其解析为Double
是微不足道的(我可以使用read
),但精度的损失是痛苦的。我需要非常小心Double
比较(我不是),这似乎是多余的,因为在Haskell中有一个Rational
数据类型。
尝试使用时,我发现要read
Rational
,numerator % denominator
必须提供以下格式的字符串:Rational
,我显然不会有
所以,问题是:
将分数的十进制表示形式解析为{{1}}的最简单方法是什么?
外部依赖的数量也应该考虑在内,因为我无法在在线评判中安装额外的库。
答案 0 :(得分:17)
您想要的功能是Numeric.readFloat
:
Numeric Data.Ratio> fst . head $ readFloat "0.75" :: Rational
3 % 4
答案 1 :(得分:3)
以下内容(GHCi会议):
> :m + Data.Ratio
> approxRational (read "0.1" :: Double) 0.01
1 % 10
当然你必须适当地选择你的epsilon。
答案 2 :(得分:1)
也许你会在竞赛中获得额外的积分来实现它:
import Data.Ratio ( (%) )
readRational :: String -> Rational
readRational input = read intPart % 1 + read fracPart % (10 ^ length fracPart)
where (intPart, fromDot) = span (/='.') input
fracPart = if null fromDot then "0" else tail fromDot