为什么使用Machin公式计算pi的值会给出错误的值?

时间:2016-09-27 14:43:00

标签: python math pi

对于我的学校项目,我试图计算使用不同方法的价值。我发现的公式之一是可以使用arctan(x)的泰勒展开计算的Machin公式。

我在python中编写了以下代码:

   π = (16 * Summation of (((-1)^n) / 2n+1) * ((1/5)^(2n+1))) - (4 * Summation of (((-1)^n) / 2n+1) * ((1/239)^(2n+1)))    

问题在于,无论循环重复多少次,我都会获得正确的pi值,直到15位小数。

例如:

第一次循环重复11次

pi = 3.141592653589793408632493

第一次循环100次重复

pi = 3.141592653589793410703296

我没有增加第二个循环的重复次数,因为arctan(1/239)非常小并且重复次数达到非常小的值,因此不应该只影响小数点后15位的pi值。

额外信息:

Machin Formula声明:

call_user_func_array

1 个答案:

答案 0 :(得分:5)

这么多条款足以让你超过50个小数位。问题是你将Python浮点数与Decimals混合在一起,所以你的计算会被那些浮点数中的错误所污染,这些错误只能精确到53位(大约15位十进制数字)。

您可以通过更改

来解决这个问题
c = pow(decimal.Decimal(1/5), decimal.Decimal(b))

c = pow(1 / decimal.Decimal(5), decimal.Decimal(b))

c = pow(decimal.Decimal(5), decimal.Decimal(-b))

显然,需要对

进行类似的更改
c = pow(decimal.Decimal(1/239), decimal.Decimal(b))

您可以使代码 lot 更具可读性。对于初学者,你应该把计算arctan系列的东西放到一个函数中,而不是将它复制到arctan(1/5)和arctan(1/239)。

此外,您不需要为所有内容使用Decimal。您可以将简单的Python整数用于counta之类的内容。例如,您对a的计算可以写为

a = (-1) ** count

或者你可以在循环外部将a设置为1,并在每次循环时将其否定。

这是您的代码的更紧凑版本。

import decimal

decimal.getcontext().prec = 60 #Setting precision

def arccot(n, terms):
    base = 1 / decimal.Decimal(n)
    result = 0
    sign = 1
    for b in range(1, 2*terms, 2):
        result += sign * (base ** b) / b
        sign = -sign
    return result

pi = 16 * arccot(5, 50) - 4 * arccot(239, 11)
print(pi)

<强>输出

3.14159265358979323846264338327950288419716939937510582094048

最后4位数字是垃圾,但其余的都很好。