【发布时间】:2019-07-08 04:26:03
【问题描述】:
我试图将所有 n 从 1 加到一个非常大的数字(现在为 10**9),但它会导致堆栈溢出。此外,我不认为在 1 处停止并在不同行中求和 n 是最有效的方法,但下面的代码是我对 Haskell 的全部知识。我真的不太了解函数式编程,我想尽可能多地解释一下。 (我也试过把 $! strict 放在最后一行,这在其他地方被告知,但它没有改变。如果你解释我可以做这个递归函数的最有效的方法,我会很高兴。)
main :: IO()
summ 1 = 1
summ n = 1/(n**2) + summ (n-1)
expected_value = pi*pi/6
errorPercent n = n / expected_value * 100
main = do
putStr "%"
print (errorPercent (summ $! (10**9)))
【问题讨论】:
-
哦对了,你可以把
summ写成summ n = sum [ 1 / i^2 | i <- [1..n] ]。不错,对吧? (确保在编译时对此进行了优化) -
@luqui - 我想你希望
sum [ 1 / i^2 | i <- reverse [1..n] ]避免精度损失。 -
@Omnifarious 有趣!我从来没有想过这样的问题。我不太明白为什么会这样......
-
@luqui - 由于四舍五入而发生。当加在一起的数字大小相似时,浮点数效果最好。否则,从小数中添加的位会从大数的末尾旋转,甚至不会改变它。所以,即使你添加了几十万个这样的小数字,它们根本不会改变原来的数字。
-
@luqui - 根据经验,是的。我还可以想象,在某些特定情况下,不同的排序可能会更好。其他操作也有其他规则。我不知道它们都是什么,但我知道充分利用浮点精度需要仔细考虑。
标签: haskell recursion stack-overflow