23

我一直在思考这个问题,但我无法弄清楚。也许你可以帮助我。问题是我的代码无法以 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))现在只是一个填充物。我知道所有代码是如何工作的,但就像我之前所说的,我无法让它射出那个代码。

4

11 回答 11

37

如果您不想实现自己的算法,可以使用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

参考

更新:代码支持旧版和新版SymPy安装(见评论)。*

于 2012-11-09T22:30:52.997 回答
23

运行这个

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并从这里 阅读运算符: “yield”关键字有什么作用?

这是答案:

3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170679821480865132823066470938446095505822317253594081284811174502841027019385211055596446229489549303819644288109756659334461284756482337
于 2012-01-25T15:22:38.633 回答
6

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

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)))

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

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

deeplook对Gist 的所有功劳。

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

于 2019-03-03T09:25:06.580 回答
2

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

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)
于 2019-07-21T11:50:08.153 回答
2

5-6年前我用下面的公式解决了。

类似机器的公式

维基百科:https ://en.wikipedia.org/wiki/Machin-like_formula

数学公式

对不起代码质量。变量名可能没有意义。

#-*- coding: utf-8 -*-

# Author:    Fatih Mert Doğancan
# Date:      02.12.2014

def arccot(x, u):
    sum = ussu = u // x
    n = 3
    sign = -1
    while 1:
        ussu = ussu // (x*x)
        term = ussu // n
        if not term:
            break
        sum += sign * term
        sign = -sign
        n += 2
    return sum

def pi(basamak):
    u = 10**(basamak+10)
    pi = 4 * (4*arccot(5,u) - arccot(239,u))
    return pi // 10**10

if __name__ == "__main__":
    print pi(1000) # 1000 
于 2020-01-27T11:14:03.233 回答
2

对于最多 100 万位的 pi,请使用math_pi(注意:我是该模块的作者)

使用 pip 安装:

pip install math-pi

在 Python 中:

>>> import math_pi
>>> print(math_pi.pi(b=1000))
3.1415926535...
于 2020-06-24T12:39:55.717 回答
1

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

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

for digit in make_pi():
    print digit

请注意,此循环是无限的: make_pi()从不抛出StopIteration

于 2012-01-25T15:08:49.727 回答
1

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

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

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

于 2014-12-01T13:16:18.193 回答
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:])
于 2012-01-25T15:14:29.357 回答
0

这是我在这里找到的另一种方式-> Python pi计算?根据 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。

于 2015-10-22T21:11:35.650 回答
0

瓦利斯公式可以得到 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)
于 2018-01-16T03:00:37.113 回答