我编写了一个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。为什么会发生这种事?
发布于 2017-03-13 21:54:19
原因如下:
> 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,所以没有任何元素被放入输出列表中。
引用Haskell 2010报告的话
序列
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的输出不会像[]那么令人惊讶。
https://stackoverflow.com/questions/42773864
复制相似问题