私の学校のプロジェクトでは、さまざまな方法を使用することの価値を計算しようとしていました。私が見つけた式の1つは、arctan(x)のテイラー展開を使用して計算できるマチン式でした。
私はPythonで次のコードを書きました:
import decimal
count = pi = a = b = c = d = val1 = val2 = decimal.Decimal(0) #Initializing the variables
decimal.getcontext().prec = 25 #Setting percision
while (decimal.Decimal(count) <= decimal.Decimal(100)):
a = pow(decimal.Decimal(-1), decimal.Decimal(count))
b = ((decimal.Decimal(2) * decimal.Decimal(count)) + decimal.Decimal(1))
c = pow(decimal.Decimal(1/5), decimal.Decimal(b))
d = (decimal.Decimal(a) / decimal.Decimal(b)) * decimal.Decimal(c)
val1 = decimal.Decimal(val1) + decimal.Decimal(d)
count = decimal.Decimal(count) + decimal.Decimal(1)
#The series has been divided into multiple small parts to reduce confusion
count = a = b = c = d = decimal.Decimal(0) #Resetting the variables
while (decimal.Decimal(count) <= decimal.Decimal(10)):
a = pow(decimal.Decimal(-1), decimal.Decimal(count))
b = ((decimal.Decimal(2) * decimal.Decimal(count)) + decimal.Decimal(1))
c = pow(decimal.Decimal(1/239), decimal.Decimal(b))
d = (decimal.Decimal(a) / decimal.Decimal(b)) * decimal.Decimal(c)
val2 = decimal.Decimal(val2) + decimal.Decimal(d)
count = decimal.Decimal(count) + decimal.Decimal(1)
#The series has been divided into multiple small parts to reduce confusion
pi = (decimal.Decimal(16) * decimal.Decimal(val1)) - (decimal.Decimal(4) * decimal.Decimal(val2))
print(pi)
問題は、ループが繰り返される回数に関係なく、小数点以下15桁までしかpiの正しい値を取得できないことです。
例えば:
最初のループの11回の繰り返しで
pi = 3.141592653589793408632493
最初のループの100回の繰り返しで
pi = 3.141592653589793410703296
arctan(1/239)は非常に小さく、数回の繰り返しで非常に小さい値に達するため、2番目のループの繰り返しを増やしていません。したがって、小数点以下15桁のpiの値に影響を与えることはありません。
追加情報:
マチンの公式は次のように述べています。
π = (16 * Summation of (((-1)^n) / 2n+1) * ((1/5)^(2n+1))) - (4 * Summation of (((-1)^n) / 2n+1) * ((1/239)^(2n+1)))
その数の用語は、小数点以下50桁を超えるのに十分です。問題は、PythonのfloatとDecimalsを混在させているため、計算がこれらのfloatのエラーで汚染されていることです。エラーは53ビット(10進数で約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))
あなたはあなたのコードを作ることが多く、読みやすいです。手始めに、arctan(1/5)とarctan(1/239)に複製するのではなく、arctanシリーズを計算するものを関数に入れる必要があります。
また、すべてにDecimalを使用する必要はありません。count
やなどの単純なPython整数を使用でき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桁はごみですが、残りは問題ありません。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加