2016-09-27 27 views
3

對於我的學校項目,我試圖計算使用不同方法的價值。我發現的一個公式是可以使用arctan(x)的泰勒展開計算的Machin公式。爲什麼使用Machin Formula給出一個錯誤的值來計算pi的值?

我寫了下面的代碼在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) 

的問題是,我得到PI的權值只能做到15個個小地方,無論是循環重演的次數。

例如:

在第一循環的11次重複

PI = 3.141592653589793408632493

在100次循環的第一循環

pi的= 3.141592653589793410703296

我不由於arctan(1/239)非常小並且達到極小的v,所以增加第二個循環的重複次數只需要重複幾次,因此不應影響只有15位小數的pi值。

附加信息:

的梅欽公式指出:

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

我沒有檢查你的代碼,但寫入Decimal(1/5)沒有問題嗎?它不提供0.2但是0.2000 .... 1110223024 ...因爲1/5首先被轉換爲浮點數並且float不能精確地存儲0.2。寫入十進制(1)/十進制(5)可準確提供0.2 – Jal

回答

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)) 
來進行

你可以讓你的代碼很多更具可讀性。對於初學者來說,你應該將計算arctan系列的東西放入一個函數中,而不是將其複製爲arctan(1/5)和arctan(1/239)。

此外,你不需要使用十進制的的一切。您可以使用簡單的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位是垃圾,但其餘的都是精品。