我在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
。
为什么会这样?
答案 0 :(得分:4)
原因如下:
> let y :: Float ; y = fromInteger (100000000 :: Integer)
> y == y-1
True
> [y, y-1 .. 1]
[]
基本上,Float
不能从10 ^ 8向下计数到1,单位步数。
舍入错误使y
和y-1
的数字相同,因此符号[y,y-1 .. 1]
被解释为增加的序列,例如[10,10 .. 1]
。由于起始值已经超过1
,因此没有元素放在输出列表中。
序列
enumFromThenTo e1 e2 e3
是列表[e1,e1 + i,e1 + 2i,…e3]
,其中增量i
为e2 − e1
。如果增量是 正数或零,列表在下一个元素结束时终止 大于e3
;如果e1 > e3
,则列表为空。如果增量是 否定,当下一个元素小于时,列表终止e3
;如果e1 < e3
,则列表为空。
可以说,Haskell应该有不同的符号来增加和减少范围。对于[y, y-1 .. 1]
,我猜repeat y
的输出效果不如[]
。