pi/2 = 1 + 1/3 + (1*2) / (3*5) + (1*2*3) / (3*5*7) + ...
好的,让我们再试一次。
我需要编写一个函数,它将max error作为pi值的参数,并返回pi的计算值和到达该点所需的迭代次数。我不能使用递归算法。
到目前为止,我有:
def piEuler (x):
count = 0.0
approx = 0.0
approx2 = 1.0
error = math.pi/2 - approx2
while error > x:
count = count + 1
approx3 = approx + approx2
error = math.pi/2 - approx3
#print error
approx = approx + approx2
approx2 = approx2 * count/(count + 2)
#print approx2
final = math.pi - error
return final, count
问题是该程序返回负值。误差应该收敛到零。我需要能够从pi的可接受值中减去我的误差,以从系列中获得近似值。我做错了什么?
答案 0 :(得分:2)
这有效:
import math
def piEuler(x):
halfpi = math.pi / 2.0
count = 0
approx = 1.0
divisor = 1
numerator = 1
while True:
count += 1
numerator *= count
divisor *= 2*count + 1
approx += float(numerator) / float(divisor)
error = halfpi - approx
if error < x:
return (math.pi - error), count
基本差异是:
答案 1 :(得分:1)
看起来你错误地实现了算法。看起来你的代码正在pi/2 = 1 + 1/3 + (1*2)/(3*5) + (1*2*3)/(3*5*7) + ...
,而不是pi/2 = 1 + 1/3 + (1*2)/(3*4) + (1*2*3)/(3*4*5) + ...
。
由于分母最终会变小,你将会增加更多的金额,这无疑会导致超调,从而产生负面错误。
问题出在这一行:
approx2 = approx2 * count/(count + 2)
正如您所看到的,当count
为偶数时,count + 2
将是均匀的。一个简单的解决方法是将其更改为:
approx2 = approx2 * count/(2 * count + 1)
这是一个有效的示例算法,但是使用术语之间的相对误差而不是绝对误差(不想让所有东西都消失;)):
from __future__ import division
def half_pi(max_err=10**-6, max_iter=10000):
partial_sum = cur_term = 1
n = 1
while abs(t) > max_err and n < max_iter:
cur_term = cur_term * (n / (2 * n + 1))
partial_sum += cur_term
n += 1
return partial_sum, n
答案 2 :(得分:0)
您应该尝试重写例程,使代码中的最小项 approx2 必须大于错误。
您在上次错误计算中也有'math.pi'。它必须是math.pi / 2吗?
似乎错误的本质也在振荡!