您的位置:首页 > 其它

分析外星人计算Pi的程序

2006-11-05 21:57 441 查看
有一个只用4行代码就实现的计算Pi的程序,被称为外星人计算Pi的程序。

有许多人讨论分析了该程序的实现原理,如:http://blog.csdn.net/panqiaomu/archive/2006/05/07/711776.aspx

但我总感觉它分析得不够透彻,于是自己分析了一下。

1.将原程序修改成更易看懂的形式;

2.采用同样的算法,用Excel表格将Pi算了出来。

下载(注意修改下载后的扩展名)


/*
File:      Pi800.c
Name:      分析外星人计算PI的程序
Author:    zyl910
Blog:      http://blog.csdn.net/zyl910/
Version:   V1.0
Updata:    2006-11-5

分析外星人计算PI的程序
~~~~~~~~~~~~~~~~~~~~~~

原始程序:
int a=10000,b,c=2800,d,e,f[2801],g;
main() {
 for(;b-c;)
    f[b++]=a/5;
 for(;d=0,g=c*2;c -=14,printf("%.4d",e+d/a),e=d%a)
    for(b=c; d+=f[b]*a,f[b]=d%--g,d/=g--,--b; d*=b);
}

算Pi公式:
          1          2          3                    k
pi = 2 + --- * (2 + --- * (2 + --- * (2 + ...  (2 + ---- * (2 + ... ))...)))
          3          5          7                   2k+1

*/

int main(void)
{
 long a=10000;// 缩放系数
 long c=2800; // 迭代次数
 long f[2801];// 中间计算结果
 long d;      // 内循环误差累计项
 long e=0;    // 外循环误差累计项
 long b, g;   // 分子 与 分母. k/(2k+1)
 int i, j;

for(i=0; i<c; i++) // 若完全依照公式,循环条件应为“for(i=1; i<=c; i++)”。幸好f[2800]的贡献非常小,取任意值都不会对精度造成太大的影响
  f[i] = 2 * a/10; // 2就是公式中的系数2。 a/10的意思是保留一个十进制位,因为输出是从个位3开始的
 while(c > 0)
 {
  d = 0;
  g = (c*2 + 1) - 2;      // 分母。因为每次循环都输出了4位,所以在后面运算时乘以了a,所以这里得 -2
  b = c;                  // 分子
  while(b > 0)
  {
   /* 根据公式,乘以分子 */
   d *= b;
   d += f[b]*a;  // 因为每次外循环都输出了4位
   /* 根据公式,除以分母 */
   f[b] = d % g; // 带分数的 分子部分
   d /= g;       // 带分数的 整数部分
   /* Next */
   g -= 2;
   b--;
  }
  printf("%.4d", e+d/a);
  e = d % a;
  c -= 14; // 因为精度固定为800位,每输出4位后,相当于精度需求降低了4位,所以每次可以少算14项
 }
 printf("/n");
 return 0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: