前段时间(我不记得在哪里)我发现这个python片段实现了一个用于计算Pi数字的插口算法:
def pi_digits():
"""generator for digits of pi"""
q,r,t,k,n,l = 1,0,1,1,3,3
while True:
if 4*q+r-t < n*t:
yield n
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 = pi_digits()
for i in range(30): print digits.next()
现在我想在C ++中实现它。我的尝试是:
#include <cmath>
#include <cstdlib>
#include <iostream>
typedef long long ll;
void help() {
std::cout << "Usage: pi2 <digits>" << std::endl;
exit(1);
}
void pi(const long long digits) {
ll q, r, t, k, n, l;
q=1;
r=0;
t=1;
k=1;
n=3;
l=3;
for(ll i=0; i<digits; ++i) {
if(4*q+r-t < n*t) {
std::cout << n;
q=10*q;
r=10*(r-n*t);
n = ( 10 * ( 3 * q + r) / t ) - 10 * n; //Thanks to maverik
} else {
q=q*k;
r=(2*q+r)*l;
t=t*l;
k=k+1;
n=(q*(7*k+2)+r*l)/(t*l);
l=l+2;
}
}
}
int main(int argc, char** argv) {
if(argc<2) help();
ll digits = 0;
if(digits=atoll(argv[1])<1) help();
pi(digits);
return 0;
}
但它永远不会调用std :: cout :: operator&lt;&lt;,而python版本可以工作。 你能救我吗?
感谢。
答案 0 :(得分:2)
原因是您的代码没有执行两种语言的等效计算。
(据我所知)有两个原因:
在这个python代码中,所有计算都是在同一时间完成的:
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)
在C代码中,计算一次执行一次,因此每个人都使用前一个的结果而不是使用旧值(如python代码那样)。
您在python中使用int
,在C中使用long long
s。
C代码中的除法将产生long long
s,而python中的除法(假设为python 2)将产生向下舍入的int
。
这也可能造成误算,导致你的情况永远不会成真。
P.S。 从头开始在C中实现这可能比移植python算法更好。
答案 1 :(得分:1)
看起来应该有(根据python代码):
n = ( 10 * ( 3 * q + r) / t ) - 10 * n;
然后:
if ( 4 * q + r - t < n * t) ...
或者我错过了什么?