分数型的比较

时间:2011-05-18 00:47:55

标签: haskell floating-point equality

ghci> 4 == 3.9999999999999999
True

ghci> 10.2^2 == 104.04
False

为什么第二个表达式返回False?

4 个答案:

答案 0 :(得分:9)

浮点值没有合理的概念。可以说,在Haskell中,表达式甚至类型检查是错误的。该问题对于使用浮点表示的所有语言都是通用的。

关于浮点的一些参考:

如果您需要正确的数学运算,请考虑使用the Rational type in Haskell,但请注意,它支持的操作范围较小,硬件支持较少。

Prelude> 4 == (3.9999999999999 :: Rational)
False
Prelude> 10.2^2 == (104.04 :: Rational)
True

答案 1 :(得分:8)

答案 2 :(得分:3)

当相等测试对浮点数执行和不执行时

您应该了解计算机内存中浮点数的表示。请参阅其他答案以获取有用的链事实上,严格比较(==)几乎不可能对他们有效。

大多数实数无法用机器浮点精确表示。其中只有少数(例如i/2^n,其中in是整数)被精确表示。其他人不是。这意味着,通常情况下,相等性测试对浮点数具有不可预测的结果,并且您可以使用它的唯一情况是当您知道数字是上述形式的修道院时。在规划和编写测试时,这可能很有效。

三种方法

解决方法是在大多数情况下对浮点数使用小于大于的测试(或使用有理数)。当您仍想比较两个浮点数时(例如在测试中),您可以定义比较的准确性。

ghci> let eq tol a b = tol > abs (a-b)
ghci> eq 1e-6 4 3.9999999999999999
True
ghci> eq 1e-6 (10.2^2) 104.04
True

您还可以考虑使用ieee754包中的(~==)近似比较。但是在大多数实际计算中结果的准确性远低于加工浮点类型的精度,因此允许一些错误仍然是有意义的。

答案

  

为什么第二个表达式返回False?

104.04应该是2601/25,而不是i/2^n形式的数字,因此无法用浮点数精确表示(GHCi默认为Double)。所以碰巧在你的平台上10.2 ^ 2不等于104.04。在另一个平台上,他们可能碰巧是平等的。

但是,如果您使用有理数,它们将是相等的:

ghci> (102%10)^2 == (10404%100)
True

答案 3 :(得分:1)

这只是一个四舍五入的案例。如果您只是在GHCI中输入3.9999999999999999,您会看到它四舍五入为4.0,显然等于4. 10.2 ^ 2的计算结果为104.03999999999999,它不会四舍五入,不等于104.04。它可能已经知道错误评估的原因是floating-point arithmetic problems