我正在编写一个函数,我需要在其中读取一个包含浮点数的字符串并将其转回 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 回答