python中的1000位pi

问题描述 投票:17回答:8

我一直在考虑这个问题,我无法弄明白。也许你可以帮助我。问题是我的代码无法在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 

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

python pi
8个回答
21
投票

运行这个

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 

并从这里阅读yield运算符:What does the "yield" keyword do?

这是答案:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337

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

Reference

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


1
投票

我不熟悉你的算法。它是BBP的实现吗?

无论如何,你的make_pi是一个发电机。尝试在for循环中使用它:

for digit in make_pi():
    print digit

请注意,这个循环是无限的:make_pi()永远不会抛出StopIteration


1
投票

在这里,您可以检查您的程序是否输出正确的1000位数:http://spoj.com/CONSTANT

当然你也可以使用diff或tc,但是你必须从某个地方复制这1000个数字,你只需要提交程序并检查分数是否大于999。

您可以尝试在那里打印更多数字,从而获得更多积分。也许你会喜欢它。


0
投票

这样做你想要的吗?

i = 0;
pi_str = ""
for x in make_pi():
    pi_str += str(x)
    i += 1
    if i == 1001:
        break

print "pi= %s.%s" % (pi_str[0],pi_str[1:])

0
投票

这是我在这里找到的另一种方式 - > Python pi calculation?基于Chudnovsky兄弟公式生成Pi来近似python,我已经为我的程序进行了严格的修改。

def pifunction():
    numberofdigits = int(input("please enter the number of digits of pi that you want to generate"))
    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))

我希望这会有所帮助,因为您可以生成任何想要生成的pi数字。


0
投票

wallis公式可以达到3.141592661439964,但需要一种更有效的方法来解决这个问题。

https://www.youtube.com/watch?v=EZSiQv_G9HM

现在是我的代码

x, y, summing = 2, 3, 4

for count in range (0,100000000):
    summing *= (x/y)
    x += 2
    summing *= (x/y)
    y += 2
    print (summing)

0
投票

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

OP的代码似乎是基于从Spigot's algorithm复制的here的实现。

要根据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)))

此外,这是一个更快的*实现,也显然基于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)))

我对this在线Pi数字发生器进行了几次测试。

所有归功于thisdeeplook Gist。

*基于测试10,000位数,我大约7秒,而大约1秒。


0
投票

来自Fabrice Bellard网站:Pi Computation算法。很抱歉这么简单的实施。 1000足够快(对我来说是0.1秒),但10000不是那么快 - 71s :-(

import time
from decimal import Decimal, getcontext

def compute(n):
    getcontext().prec = n
    res = Decimal(0)
    for i in range(n):
        a = Decimal(1)/(16**i)
        b = Decimal(4)/(8*i+1)
        c = Decimal(2)/(8*i+4)
        d = Decimal(1)/(8*i+5)
        e = Decimal(1)/(8*i+6)
        r = a*(b-c-d-e)
        res += r
    return res

if __name__ == "__main__":
    t1 = time.time()
    res = compute(1000)
    dt = time.time()-t1
    print(res)
    print(dt)
© www.soinside.com 2019 - 2024. All rights reserved.