在 Python 中使用 Chudnovsky 算法计算 Pi 时我变得不准确
I am getting innaccuracy when computing Pi using Chudnovsky algorithm in Python
我是 Python(和一般编码)的初学者,我正在尝试将 Pi (π) 计算到小数点后 1000 位,以提高我的学习效果。我正在使用 Chudnovsky 算法,因为它非常简单,并且比大多数其他算法用更少的迭代收敛。
更多信息:http://en.wikipedia.org/wiki/Chudnovsky_algorithm
This is the formula that I am using.
但是,我设法只获得了前 10 位数字的准确性 :( 。我还设法从一个网站上获得了一个现有的解决方案,这非常有效!我试图在不失去可读性和可读性的情况下调整我的代码使用相同的参数执行两个代码块以消除可能导致问题的其他因素。但问题仍然存在。
有人可以指出(为了我的学习)错误发生在哪里以及为什么吗?
这是我的代码,供您 运行 并亲自查看结果:
Python 3.7.6
from decimal import Decimal, getcontext
def factorial(x):
'''
Function to perform a factorial operation on a given argument. Returns factorial value.
'''
if x < 1:
return 1
else:
return x * factorial(x-1)
def chudnovsky01(iterations):
'''
http://en.wikipedia.org/wiki/Chudnovsky_algorithm
Computes approximation of pi as per chudivsky algorithm.
This is the code block that is giving innacuracy.
'''
sum_term = Decimal(0) #setting sumterm as zero
C = Decimal(10005).sqrt() / 4270934400 #defining the Constant term
for k in range(0,iterations): #defining the summation loop
M = Decimal(factorial(6*k))/(factorial(k)**3)*factorial(3*k) #defining the Multinomial term
L = 13591409+(545140134*k) #defining the Linear term
X = Decimal(640320**(k*3)) #defining the Exponential term
sum_term += Decimal((-1)**k)*M*L/X #Calculating the sum-term
pi = sum_term*C #Multiplying the Constant & Sum-term
pi = pi**(-1) #Taking reciprocal
return pi
def chudnovsky02(n):
'''
The same algorithm picked up from a website. Same formula; harder to read but Works perfectly!
'''
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)
pi
return pi
def main():
print('******** WELCOME TO PI CALCULATOR ********\n')
precision = int(input('Enter the number of decimal places 1-1000\t'))
getcontext().prec = precision+1
iterations = 20 # Arbitrary value.Should be sufficient enough to
# get atleast 100 digits of Pi with accuracy
pi = chudnovsky01(iterations)
pi2 = chudnovsky02(iterations)
print(f'Completed! with {iterations} iterations.')
print(f'Pi: First func result:\t {pi}')
print(f'Pi: Second func result:\t {pi2}')
if __name__ == '__main__':
main()
可以在这里找到 Pi 的前 100,000 位小数:
http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
问题是您在计算 M 时缺少括号:
M = Decimal(factorial(6*k))/(factorial(k)**3)*factorial(3*k)
应该是:
M = Decimal(factorial(6*k))/((factorial(k)**3)*factorial(3*k))
我是 Python(和一般编码)的初学者,我正在尝试将 Pi (π) 计算到小数点后 1000 位,以提高我的学习效果。我正在使用 Chudnovsky 算法,因为它非常简单,并且比大多数其他算法用更少的迭代收敛。 更多信息:http://en.wikipedia.org/wiki/Chudnovsky_algorithm
This is the formula that I am using.
但是,我设法只获得了前 10 位数字的准确性 :( 。我还设法从一个网站上获得了一个现有的解决方案,这非常有效!我试图在不失去可读性和可读性的情况下调整我的代码使用相同的参数执行两个代码块以消除可能导致问题的其他因素。但问题仍然存在。
有人可以指出(为了我的学习)错误发生在哪里以及为什么吗?
这是我的代码,供您 运行 并亲自查看结果:
Python 3.7.6
from decimal import Decimal, getcontext def factorial(x): ''' Function to perform a factorial operation on a given argument. Returns factorial value. ''' if x < 1: return 1 else: return x * factorial(x-1) def chudnovsky01(iterations): ''' http://en.wikipedia.org/wiki/Chudnovsky_algorithm Computes approximation of pi as per chudivsky algorithm. This is the code block that is giving innacuracy. ''' sum_term = Decimal(0) #setting sumterm as zero C = Decimal(10005).sqrt() / 4270934400 #defining the Constant term for k in range(0,iterations): #defining the summation loop M = Decimal(factorial(6*k))/(factorial(k)**3)*factorial(3*k) #defining the Multinomial term L = 13591409+(545140134*k) #defining the Linear term X = Decimal(640320**(k*3)) #defining the Exponential term sum_term += Decimal((-1)**k)*M*L/X #Calculating the sum-term pi = sum_term*C #Multiplying the Constant & Sum-term pi = pi**(-1) #Taking reciprocal return pi def chudnovsky02(n): ''' The same algorithm picked up from a website. Same formula; harder to read but Works perfectly! ''' 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) pi return pi def main(): print('******** WELCOME TO PI CALCULATOR ********\n') precision = int(input('Enter the number of decimal places 1-1000\t')) getcontext().prec = precision+1 iterations = 20 # Arbitrary value.Should be sufficient enough to # get atleast 100 digits of Pi with accuracy pi = chudnovsky01(iterations) pi2 = chudnovsky02(iterations) print(f'Completed! with {iterations} iterations.') print(f'Pi: First func result:\t {pi}') print(f'Pi: Second func result:\t {pi2}') if __name__ == '__main__': main()
可以在这里找到 Pi 的前 100,000 位小数: http://www.geom.uiuc.edu/~huberty/math5337/groupe/digits.html
问题是您在计算 M 时缺少括号:
M = Decimal(factorial(6*k))/(factorial(k)**3)*factorial(3*k)
应该是:
M = Decimal(factorial(6*k))/((factorial(k)**3)*factorial(3*k))