在Python中使用序列计算pi

clj7thdc  于 2022-12-10  发布在  Python
关注(0)|答案(3)|浏览(153)
pi/2 = 1 + 1/3 + (1*2) / (3*5) + (1*2*3) / (3*5*7) + ...

好吧,我们再试一次。
我需要写一个函数,把最大误差作为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值中减去误差,以从序列中得到一个近似值。我做错了什么?

iyr7buue

iyr7buue1#

这是可行的:

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.小心使用int和float数据类型(这可能是您的问题)
1.更好的变量命名会使调试更容易

xytpbqjk

xytpbqjk2#

看起来你不正确地实现了算法。你的代码不是在执行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
hsgswve4

hsgswve43#

您应该尝试重写例程,使序列中的最小项(代码中的 * approx 2 *)必须大于error。
在你最后的错误计算中也有“math.pi”。它一定是math.pi/2吗?
看来误差的性质也是振荡的!

相关问题