对于我的学校项目,我试图计算使用不同方法的价值。我发现的公式之一是可以使用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
答案 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整数用于count
和a
之类的内容。例如,您对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位数字是垃圾,但其余的都很好。