Chudnovsky算法的错误在哪里(python)?

Where is the error in Chudnovsky algorithm (python)?

我是 python 的新手(也是编码方面的新手),所以我正在学习一本教程书。我尝试使用本书概述的代码中的 Chudnovsky 算法将 pi 计算到一组小数位;但是,当我执行代码时,我收到一条错误消息:

> File "C:/Users/user/Documents/Python/Scripts/Tutorials/Calculating
> pi.py", line 15, in calc
> t = (Decimal(-1)**k)*(math.factorial(Decimal(6)*k))*(13591409 + 545140134*k) TypeError: 'decimal.Decimal' object cannot be interpreted
> as an integer

原代码如下:

from decimal import Decimal, getcontext
import math
    
    numberofdigits = int(input("please enter the number of decimal places to calculate Pi to: "))
    getcontext().prec = numberofdigits
    
    def calc(n):
        t = Decimal(0)
        pi = Decimal(0)
        deno = Decimal(0)
        k = 0
        for k in range(n):
            t = (Decimal(-1)**k)*(math.factorial(Decimal(6)*k))*(13591409+545140134*k)
            deno = math.factorial(3*k)*(math.factorial(k)**Decimal(3))*(640320**(3*k))
            pi += Decimal(t)/Decimal(deno)
        pi = pi * Decimal(12)/Decimal(640320**Decimal(1.5))
        pi = 1/pi
        return str(pi)
    
    
    print (calc(1))

我哪里错了?我已经对拼写错误等进行了三重检查,但没有发现任何东西,但我并不真正理解 decimal.decimal 类型错误的含义。

编辑: 我一直在玩弄它,发现如果我将分子的项分开,我会得到:

 def calc(n): 
    t = Decimal(0) 
    pi = Decimal(0) 
    deno = Decimal(0) 
    k = 0 for k in range(n): 
    u=(Decimal(-1)**k) 
    x=(Decimal(6)*k) 
    v=math.factorial(x) 
    w=(13591409+545140134*k) 
    t = u*v*w 
    deno = math.factorial(3*k)*(math.factorial(k)**Decimal(3))*(640320**(3*k)) 

这给了我以下错误:

第 17 行,在计算 v=math.factorial(x) TypeError: 'decimal.Decimal' object cannot be interpreted as an integer

干杯

问题似乎是 math.factorial() 函数只接受具有整数值的整数或浮点数,但不支持 Decimal 对象:

print(math.factorial(6))
# 720
print(math.factorial(6.0))
# 720
print(math.factorial(Decimal(6)))
# TypeError: 'decimal.Decimal' object cannot be interpreted as an integer

在第 15 行更改传递给 math.factorial() 的值应该可以修复错误:

t = (Decimal(-1)**k) * (math.factorial(6 * k)) * (13591409+545140134 * k)

有趣的是,您的原始代码在 Python 3.6.9 中运行良好,但在 Python 3.8.2 中失败,因为此行为是在 Python 3.8 中引入的(是的,这是预期的行为)。

通过阅读有关在 math.factorial() 中放弃对 Decimal 对象的支持的讨论,可以完全理解此行为背后的逻辑:

Issue 33083: math.factorial accepts non-integral Decimal instances