使用一系列来计算Python中的pi

时间:2013-02-22 03:35:46

标签: python python-2.7

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的可接受值中减去我的误差,以从系列中获得近似值。我做错了什么?

3 个答案:

答案 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. 通过将循环的终止条件切换为测试/中断,我可以删除系列第二项的手动计算
  2. 小心使用int和float数据类型(这可能是您的问题)
  3. 更好地命名变量可以简化调试

答案 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吗?

似乎错误的本质也在振荡!