私はpython初心者で、piを計算したい。他のアルゴリズムよりも高速だと聞いたので、Chudnovskyアルゴリズムを使用してみた。
これは私のコードです:
from math import factorial
from decimal import Decimal, getcontext
getcontext().prec=100
def calc(n):
t= Decimal(0)
pi = Decimal(0)
deno= Decimal(0)
k = 0
for k in range(n):
t = ((-1)**k)*(factorial(6*k))*(13591409+545140134*k)
deno = factorial(3*k)*(factorial(k)**3)*(640320**(3*k))
pi += Decimal(t)/Decimal(deno)
pi = pi * Decimal(12)/Decimal(640320**(1.5))
pi = 1/pi
return pi
print calc(25)
何らかの理由で、このコードは、許容値と比較して最大15桁までのpiのvakueを生成します。精度値を増やすことでこれを解決しようとしました。これにより桁数が増えますが、最初の15桁のみが正確です。アルゴリズムの計算方法を変えてみましたが、うまくいきませんでした。だから私の質問は、このコードをより正確にするためにできることがありますか、別のアルゴリズムを使用する必要がありますか?私はこの方法で助けていただければ幸いですPythonで非常に多くの数字で動作するように。プログラムによって決定および表示される(正しい)桁数(10、100、1000など)を制御できるようにしたい.
この行の精度が失われているようです:
pi = pi * Decimal(12)/Decimal(640320**(1.5))
使用してみてください:
pi = pi * Decimal(12)/Decimal(640320**Decimal(1.5))
これは、Pythonは任意のスケール整数を処理できますが、floatではうまく処理できないためです。
ボーナス
別のアルゴリズムを使用した単一行の実装( BBP式 ):
from decimal import Decimal, getcontext
getcontext().prec=100
print sum(1/Decimal(16)**k *
(Decimal(4)/(8*k+1) -
Decimal(2)/(8*k+4) -
Decimal(1)/(8*k+5) -
Decimal(1)/(8*k+6)) for k in range(100))
Pythonで任意の精度のpiを取得するための準備ができているソリューションを取得するためだけにここに来る人のために:
import decimal
def pi():
"""
Compute Pi to the current precision.
Examples
--------
>>> print(pi())
3.141592653589793238462643383
Notes
-----
Taken from https://docs.python.org/3/library/decimal.html#recipes
"""
decimal.getcontext().prec += 2 # extra digits for intermediate steps
three = decimal.Decimal(3) # substitute "three=3.0" for regular floats
lasts, t, s, n, na, d, da = 0, three, 3, 1, 0, 0, 24
while s != lasts:
lasts = s
n, na = n + na, na + 8
d, da = d + da, da + 32
t = (t * n) / d
s += t
decimal.getcontext().prec -= 2
return +s # unary plus applies the new precision
decimal.getcontext().prec = 1000
pi = pi()
from decimal import *
#Sets decimal to 25 digits of precision
getcontext().prec = 25
def factorial(n):
if n<1:
return 1
else:
return n * factorial(n-1)
def plouffBig(n): #http://en.wikipedia.org/wiki/Bailey%E2%80%93Borwein%E2%80%93Plouffe_formula
pi = Decimal(0)
k = 0
while k < n:
pi += (Decimal(1)/(16**k))*((Decimal(4)/(8*k+1))-(Decimal(2)/(8*k+4))-(Decimal(1)/(8*k+5))-(Decimal(1)/(8*k+6)))
k += 1
return pi
def bellardBig(n): #http://en.wikipedia.org/wiki/Bellard%27s_formula
pi = Decimal(0)
k = 0
while k < n:
pi += (Decimal(-1)**k/(1024**k))*( Decimal(256)/(10*k+1) + Decimal(1)/(10*k+9) - Decimal(64)/(10*k+3) - Decimal(32)/(4*k+1) - Decimal(4)/(10*k+5) - Decimal(4)/(10*k+7) -Decimal(1)/(4*k+3))
k += 1
pi = pi * 1/(2**6)
return pi
def chudnovskyBig(n): #http://en.wikipedia.org/wiki/Chudnovsky_algorithm
pi = Decimal(0)
k = 0
while k < n:
pi += (Decimal(-1)**k)*(Decimal(factorial(6*k))/((factorial(k)**3)*(factorial(3*k)))* (13591409+545140134*k)/(640320**(3*k)))
k += 1
pi = pi * Decimal(10005).sqrt()/4270934400
pi = pi**(-1)
return pi
print "\t\t\t Plouff \t\t Bellard \t\t\t Chudnovsky"
for i in xrange(1,20):
print "Iteration number ",i, " ", plouffBig(i), " " , bellardBig(i)," ", chudnovskyBig(i)