3

我正在编写一个函数,我需要在其中读取一个包含浮点数的字符串并将其转回 Rational。但是当我这样做时toRational (read input :: Double),它不会像预期的那样变成 eg: 0.99 % 10而是 81 ..... % 9007 ... Thx

4

2 回答 2

10

这是正确的行为。该数字0.9不能表示为Double,不在 Haskell、C 或 Java 中。这是因为DoubleFloat使用基数 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 回答