我被要求使用Leibniz公式以给定的精度(eps
)计算Pi的Pi编号。
该公式如下所示:
最初,我编写了以下代码:
fun main() {
val eps = 0.005
var n = 2
var r = row(n) // current row
var r0 = row(n-1)
var s = r0 + r
while (Math.abs(r) > eps) {
n++
r = row(n)
s += r
}
println(r.toString() + " <-- Leibniz(" + n.toString() + ")")
println(Math.abs(s*4).toString() + " <-- our evaluation with eps")
println(Math.PI.toString() + " <-- real Pi")
println((Math.abs(s*4)) in (Math.PI-eps..Math.PI+eps))
}
fun row(n: Int) = ((Math.pow(-1.0, n.toDouble()))/(2*n-1))
然后我发现它无法正常工作,因为println((Math.abs(s*4)) in (Math.PI-eps..Math.PI+eps))
打印false
。我更深入地进行了调试,并意识到如果
while (Math.abs(r) > eps/2)
过度while (Math.abs(r) > eps)
一切正常。有人可以提供关于我做错了什么或为什么我必须将
eps
除以2的任何解释(如果正确)。谢谢。
最佳答案
由于r_i
,该系列中的每个词sum(r_0, .., r_n) = PI/4
都加起来等于PI的4倍。因此,当然,当您在第一个r_i <= eps
处停止时,这仅意味着sum(r_0, ..., r_(i-1))
具有eps
的累计内容,即它位于[PI/4 - eps/2, PI/4 + eps/2]
之间。但是PI本身就是4*sum
,因此精度当然是4*eps
,即近似值位于[PI-2*eps ,PI+2*eps]
之间
对于eps = 0.005
的值:
r_100 = 0.00497512...
是第一个r <= eps
sum(r0, ..., r_99) = 0.782829
,因此此时的PI近似为3.1315929
编辑
另外,您实际上正在计算
-PI
,因为正在翻转系列中每个术语的符号。因此,您在代码中称r0
(它应称为r1
,因为它是row(1)
的结果)是-1
而不是+1
关于kotlin - 具有给定精度的Pi的Leibniz公式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64589152/