Haskell floor函数返回不同的结果
关于HaskellHaskell floor函数返回不同的结果,haskell,Haskell,关于Haskellfloor函数,我有一个问题-它应该返回“不大于参数的最大整数”,但返回表达式 楼层3.9999999999999 返回4而不是3。它可能与Double类型精度有关,但鉴于Haskell类型安全的重要性,它不应该编译,无论如何,在这种情况下,它返回的数字大于与其定义相矛盾的参数 在本例中,它返回的数字大于与其定义相矛盾的参数 它返回一个与其参数相等的数字。正如你所说,这是关于双精度的。在64位浮点规则下,数字3.9999999999999和4只是彼此相等 但是考虑到Haskel
floor
函数,我有一个问题-它应该返回“不大于参数的最大整数”,但返回表达式
楼层3.9999999999999
返回4而不是3。它可能与Double
类型精度有关,但鉴于Haskell类型安全的重要性,它不应该编译,无论如何,在这种情况下,它返回的数字大于与其定义相矛盾的参数
在本例中,它返回的数字大于与其定义相矛盾的参数
它返回一个与其参数相等的数字。正如你所说,这是关于双精度的。在64位浮点规则下,数字3.9999999999999和4只是彼此相等
但是考虑到Haskell类型安全的重要性,它不应该编译
问题是,像这样的分数文本具有多态类型分数a=>a
。也就是说,他们不必是双打。例如,您可以编写floor(3.9999999999999999999::Rational)
,它将正确返回3,因为3.9999999999999可以表示为Rational
,而不会损失任何精度
如果Haskell在编写3.9999999999999999
时出错,那么您也将无法编写3.9999999999999::Rational
,这将很糟糕。因此,由于一个分数文本可以使用许多不同的类型来表示,其中一些类型具有无限的精度,因此Haskell基于双重的限制来限制合法分数文本的数量将是一个巨大的错误
有人可能会说,Haskell应该限制3.9999999999999999
作为Double
使用时,而不是作为Rational
使用时。然而,这将需要分数类型类的实例声明有关其精度的信息(以便Haskell可以使用该信息来确定给定的文本是否对该类型有效),而该类目前不有效,并且在一般情况下很难(或不可能)实现,高效且用户友好的方式(考虑到术语“精度”可能意味着完全不同的东西,这取决于我们谈论的是浮点数还是固定点数,以及它们是否使用基数2或10(或任何其他)表示数字-对于分数型
类型类的实例,其中任何一个都是可能的。这与类型安全无关。例如,检查上的值。如果长度小于或等于64位,则浮点数的3.9999999999999
和4
的值完全相同。你得到的值并没有变大——完全一样
如果您需要如此高的精度,请查看无论您的浮点数格式有多少位,它都是有限的,并且将舍入无法精确表示的常量。当3.99999999999999999
转换为double时,甚至在floor
看到它之前,3.99999999999999
似乎被舍入为4.0
。我想问题是,如果用户试图编写一个double
而实际上不能正确表示为double
的并且编译器允许,那么这是一种类型错误,编译器没有捕捉到。@sepp2k:如果您希望这是一个编译错误,您应该知道这会有什么影响<例如,code>0.1
,不能用双精度(或任何二进制浮点格式iirc)精确表示。但是使(0.1::Double)
产生编译错误是不切实际的。@tauli我不想要任何东西,我是在解释OP的观点。我还认为,在这种情况下,我们可以定义“一个可以准确表示为双精度的文字”来表示“一个字符串表示将与文字等效的数字”,这将导致一些有用的规则,关于哪些文本可以被接受,哪些不可以。要求Double
文本可以精确表示会有点烦人。当您想要0.1
时,您必须编写0.10000000000000005551151231257827021181583404541015625
。