Python中的1000位圆周率
我一直在思考这个问题,但就是搞不明白。也许你能帮我一下。问题是我的代码在用Python语言输出1000位π(圆周率)时不工作。
这是我的代码:
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))
现在只是个占位符。我知道这些代码是怎么用的,但正如我之前说的,我就是无法让它正常输出。
11 个回答
9
这个被认可的答案是不对的,评论里也提到了这一点。
提问者的代码看起来是基于一种叫做Spigot算法的实现,似乎是从这里复制过来的。
为了根据提问者的问题修复代码(虽然我把变量和函数重命名了,以便和原始来源一致),一个可能的解决方案是:
#!/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)))
我对这两个实现进行了几次测试,使用的是这个在线的圆周率数字生成器。
* 根据测试10,000位数字的结果,我的实现大约需要7秒,而这个更快的实现只需要大约1秒。
27
运行这个
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