【问题标题】:Trying to import a python snippet to C/C++ (PI spigot algorithm)尝试将 python 片段导入 C/C++(PI spigot 算法)
【发布时间】:2012-12-22 14:56:51
【问题描述】:

前段时间(我不记得在哪里)我找到了这个 python sn-p,它实现了一个用于计算 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

谢谢。

【问题讨论】:

  • 为什么发布不完整的代码?我们是否应该手动添加其余部分以获得可编译的 .c 文件?
  • 我会发布完整的文件。
  • 我应该把它当作恭维吗? ;D
  • @user1923694,当然,没有提到任何冒犯:)
  • 这个算法太棒了!您可以在 5 分钟内获得一百万位数的 PI!

标签: python c algorithm pi


【解决方案1】:

原因是您的代码没有执行两种语言的等效计算。

(据我所知)有两个原因:

  1. 在这段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 代码一样)。

  2. 您在 python 中使用 ints,在 C 中使用 long longs。 C代码中的除法将产生long longs,而python(假设python 2)中的除法将产生四舍五入的ints。

    这也可能造成计算错误,从而导致您的条件永远不会成立。

附: 从头开始在 C 中实现这一点可能比移植 python 算法更好。

【讨论】:

    【解决方案2】:

    看起来应该有(根据python代码):

    n = ( 10 * ( 3 * q + r) / t ) - 10 * n;
    

    还有:

    if ( 4 * q + r - t < n * t) ...
    

    或者我错过了什么?

    【讨论】:

    • 你是对的,我在那里犯了一个错误。但这根本不能解决问题。
    • P.S 我没有看到 drop() 在您更新的代码中的某处调用
    • 嗯,这是来自该示例的旧版本。
    猜你喜欢
    • 2011-05-04
    • 1970-01-01
    • 1970-01-01
    • 2021-04-12
    • 2018-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多