如果参数超过7个零,则函数返回零

时间:2017-03-13 21:37:03

标签: haskell

我在haskell函数中写道,它以精确的方式计算pi数作为参数:

mojePi :: Integer -> Float
mojePi x = sqrt $ 6 * mySum x
    where
        mySum 1 = 1
        mySum x = sum $ map (1/) $ map (**2) [y,y-1..1]
            where
                y = fromInteger x

如果我使用10000000(7个零)运行此函数,它可以正常工作,但使用100000000(8个零)以及更多时,它会立即返回0。 为什么会这样?

1 个答案:

答案 0 :(得分:4)

原因如下:

> let y :: Float ; y = fromInteger (100000000 :: Integer)
> y == y-1
True
> [y, y-1 .. 1]
[]

基本上,Float不能从10 ^ 8向下计数到1,单位步数。

舍入错误使yy-1的数字相同,因此符号[y,y-1 .. 1]被解释为增加的序列,例如[10,10 .. 1]。由于起始值已经超过1,因此没有元素放在输出列表中。

引用Haskell 2010 report

  

序列enumFromThenTo e1 e2 e3是列表[e1,e1 + i,e1 + 2i,…e3],其中增量ie2 − e1。如果增量是   正数或零,列表在下一个元素结束时终止   大于e3;如果e1 > e3,则列表为空。如果增量是   否定,当下一个元素小于时,列表终止   e3;如果e1 < e3,则列表为空。

可以说,Haskell应该有不同的符号来增加和减少范围。对于[y, y-1 .. 1],我猜repeat y的输出效果不如[]