python中的1000位pi

bob*_*imo 19 python pi

我一直在考虑这个问题,我无法弄明白.也许你可以帮助我.问题是我的代码无法在python编码语言中输出1000位pi.

这是我的代码:

def make_pi():
    q, r, t, k, m, x = 1, 0, 1, 1, 3, 3
    while True:
        if 4 * q + r - t < m * t:
            yield m
            q, r, t, k, m, x = (10*q, 10*(r-m*t), t, k, (10*(3*q+r))//t - 10*m, x)
        else:
            q, r, t, k, m, x = (q*k, (2*q+r)*x, t*x, k+1, (q*(7*k+2)+r*x)//(t*x), x+2)

digits = make_pi()
pi_list = []
my_array = []
for i in range(1000):
    my_array.append(str("hello, I'm an element in an array \n" ))
big_string = "".join(my_array)

print "here is a big string:\n %s" % big_string 
Run Code Online (Sandbox Code Playgroud)

我知道这个代码可以修复工作,但我不知道该修复什么...这里的print语句是一个大字符串,my_array.append(str("hello, im an element in an array \n))现在只是一个填充.我知道所有的代码是如何工作的,但就像我之前说的那样,我无法用它来拍摄代码.

Gar*_*yde 30

如果您不想实现自己的算法,可以使用mpmath.

try:
    # import version included with old SymPy
    from sympy.mpmath import mp
except ImportError:
    # import newer version
    from mpmath import mp
mp.dps = 1000  # set number of digits
print(mp.pi)   # print pi to a thousand places
Run Code Online (Sandbox Code Playgroud)

参考

更新:代码支持SymPy的旧版和新版安装(请参阅注释).*

  • 当您在类似anaconda创建的环境中安装sympy时,它将分别安装`mpmath`并且import语句变为`来自mpmath import mp`.这个答案中的代码不再适用于现代版本的`sympy`.再也没有'sympy.mpmath`了. (2认同)

bat*_*tar 22

运行这个

def make_pi():
    q, r, t, k, m, x = 1, 0, 1, 1, 3, 3
    for j in range(1000):
        if 4 * q + r - t < m * t:
            yield m
            q, r, t, k, m, x = 10*q, 10*(r-m*t), t, k, (10*(3*q+r))//t - 10*m, x
        else:
            q, r, t, k, m, x = q*k, (2*q+r)*x, t*x, k+1, (q*(7*k+2)+r*x)//(t*x), x+2


my_array = []

for i in make_pi():
    my_array.append(str(i))

my_array = my_array[:1] + ['.'] + my_array[1:]
big_string = "".join(my_array)
print "here is a big string:\n %s" % big_string 
Run Code Online (Sandbox Code Playgroud)

yield从这里阅读有关运算符的信息: "yield"关键字有什么作用?

这是答案:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337
Run Code Online (Sandbox Code Playgroud)

  • "for j in range(1000)"使其生成的数字远远少于1000位.这应该改回"真实"或其他一些条件. (3认同)
  • 我真的不喜欢这个代码,拳头 - 你改变了"make_pi"函数有一些限制,甚至没有尝试将它提取到参数,但即使这样也不需要 - make_pi()返回一个生成器,你可以使用.next读取它()你想要多次,为什么要两次调用make_pi? (2认同)

Ale*_*vey 5

如评论中所述,接受的答案不正确。

OP 的代码似乎基于从此处复制的Spigot 算法的实现。

要根据 OP 的问题修复代码(尽管我重命名了变量和函数以匹配它们在原始源中的内容),一种解决方案可能是:

#!/usr/bin/env python

DIGITS = 1000

def pi_digits(x):
    """Generate x digits of Pi."""
    q,r,t,k,n,l = 1,0,1,1,3,3
    while x >= 0:
        if 4*q+r-t < x*t:
            yield n
            x -= 1
            q,r,t,k,n,l = 10*q, 10*(r-n*t), t, k, (10*(3*q + r))/t-10*n, l
        else:
            q,r,t,k,n,l = q*k, (2*q+r)*l, t*l, k+1, (q*(7*k+2)+r*l)/(t*l), l+2

digits = [str(n) for n in list(pi_digits(DIGITS))]
print("%s.%s\n" % (digits.pop(0), "".join(digits)))
Run Code Online (Sandbox Code Playgroud)

此外,这是一个更快*的实现,显然也基于 Spigot 的算法:

#!/usr/bin/env python

DIGITS = 1000

def pi_digits(x):
    """Generate x digits of Pi."""
    k,a,b,a1,b1 = 2,4,1,12,4
    while x > 0:
        p,q,k = k * k, 2 * k + 1, k + 1
        a,b,a1,b1 = a1, b1, p*a + q*a1, p*b + q*b1
        d,d1 = a/b, a1/b1
        while d == d1 and x > 0:
            yield int(d)
            x -= 1
            a,a1 = 10*(a % b), 10*(a1 % b1)
            d,d1 = a/b, a1/b1

digits = [str(n) for n in list(pi_digits(DIGITS))]
print("%s.%s\n" % (digits.pop(0), "".join(digits)))
Run Code Online (Sandbox Code Playgroud)

我对这个在线 Pi 数字生成器进行了几次测试。

deeplook将此归功于Gist 。

* 基于测试 10,000 位数字,与大约 1 秒相比,我得到了大约 7 秒。