我正在编写一个函数,我需要在其中读取一个包含浮点数的字符串并将其转回 Rational。但是当我这样做时toRational (read input :: Double)
,它不会像预期的那样变成 eg: 0.9
,9 % 10
而是 81 ..... % 9007 ... Thx
问问题
1756 次
2 回答
10
这是正确的行为。该数字0.9
不能表示为Double
,不在 Haskell、C 或 Java 中。这是因为Double
并Float
使用基数 2:它们只能准确地表示二元分数的某个子集。
要获得您想要的行为,请导入Numeric
模块并使用该readFloat
函数。该接口相当不稳定(它使用ReadS
类型),因此您必须稍微包装一下。以下是您可以使用它的方法:
import Numeric
myReadFloat :: String -> Rational -- type signature is necessary here
myReadFloat str =
case readFloat str of
((n, []):_) -> n
_ -> error "Invalid number"
而且,结果:
> myReadFloat "0.9"
9 % 10
于 2010-04-01T00:37:30.117 回答
2
二进制浮点数不能精确地表示以 10 为底的所有数字。您看到的数字 0.9 并不完全是0.9,而是非常接近它。永远不要在需要小数精度的地方使用浮点类型——他们就是做不到。
于 2010-04-01T00:35:01.507 回答