Haskell 双有理数问题

Haskell 双有理数问题,haskell,double,rational-number,Haskell,Double,Rational Number,我正在编写一个函数,在这个函数中,我需要读取一个包含浮点数的字符串,并将其转换回Rational。但是当我执行torional(read input::Double)时,它不会像预期的那样将例如:0.9转换为9%10,而是81%…%9007... 二进制浮点数不能精确地表示基数为10的所有数字。你看到的数字0.9并不完全是0.9,而是非常接近它。千万不要在需要小数精度的地方使用浮点类型,因为它们就是做不到。这是正确的行为。数字0.9不能表示为Double,不能用Haskell、C或Java表示

我正在编写一个函数,在这个函数中,我需要读取一个包含浮点数的字符串,并将其转换回Rational。但是当我执行
torional(read input::Double)
时,它不会像预期的那样将例如:
0.9
转换为
9%10
,而是81%…%9007...
二进制浮点数不能精确地表示基数为10的所有数字。你看到的数字0.9并不完全是0.9,而是非常接近它。千万不要在需要小数精度的地方使用浮点类型,因为它们就是做不到。

这是正确的行为。数字
0.9
不能表示为
Double
,不能用Haskell、C或Java表示。这是因为
Double
Float
使用基数2:它们只能精确地表示并矢分数的某个子集

要获得所需的行为,请导入
Numeric
模块并使用
readFloat
函数。该界面相当不稳定(它使用
读取
类型),因此您必须对其进行一些包装。以下是如何使用它:

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

如果要处理负数,请使用“readSigned readFloat”。