我有一个关于 Haskellfloor
函数的问题 - 它应该返回“不大于参数的最大整数”但是表达式
floor 3.9999999999999999
返回 4 而不是 3。它可能与Double
类型精度有关,但考虑到 Haskell 类型安全的重要性,它不应该编译,无论如何在这种情况下它返回的数字大于与其定义相矛盾的参数。
我有一个关于 Haskellfloor
函数的问题 - 它应该返回“不大于参数的最大整数”但是表达式
floor 3.9999999999999999
返回 4 而不是 3。它可能与Double
类型精度有关,但考虑到 Haskell 类型安全的重要性,它不应该编译,无论如何在这种情况下它返回的数字大于与其定义相矛盾的参数。
在这种情况下,它返回大于与其定义相矛盾的参数的数字。
它返回一个等于其参数的数字。正如你所说,这是关于双精度。在 64 位浮点规则下,数字 3.9999999999999999 和 4 完全相等。
但是考虑到 Haskell 类型安全的重要性,它不应该编译
问题是像这样的分数文字具有多态类型Fractional a => a
。那就是他们不必是双打。例如,您可以编写floor (3.9999999999999999 :: Rational)
3,因为 3.9999999999999999 可以表示为 aRational
而不会损失任何精度。
如果 Haskell 写错了3.9999999999999999
,那么你也不能写3.9999999999999999 :: Rational
,这很糟糕。因此,由于Fractional
可以使用许多不同的类型来表示文字,其中一些具有无限精度,因此 HaskellFractional
根据Double
' 的限制来限制合法文字的数量将是一个大错误。
有人可能会争辩说,Haskell3.9999999999999999
在用作 a 时应该限制Double
,而不是在用作 a 时Rational
。但是,这将需要Fractional
类型类的实例来声明有关其精度的信息(以便 Haskell 可以使用该信息来确定给定的文字是否对该类型有效),而这目前还没有,这将是困难的(或不可能的)以通用、高效和用户友好的方式实现(考虑到“精度”一词的含义可能完全不同,具体取决于我们谈论的是浮点数还是定点数,以及它们是使用基数 2 还是 10 (或其他任何东西)来表示数字 - 对于Fractional
类型类的实例,其中任何一个都是可能的)。
这与类型安全无关。例如,检查http://babbage.cs.qc.cuny.edu/IEEE-754/上的值。3.9999999999999999
如果长度小于或等于 64 位,则和的值4
对于浮点数完全相同。你得到的价值并不大——它是完全一样的。
如果您需要如此高的精度,请查看http://www.haskell.org/haskellwiki/Libraries_and_tools/Mathematics#Arbitrary_precision