文档介绍:求 PI 破解求 pi 的怪异程序 Cong Wang 25th November,2005 Institute of Post and munication, Xi'an, PRC work Engineering Dep. 引言网上流传着一个怪异的求 pi 程序, 虽然只有三行却能求出 pi 值连小数点前共 800 位。这个程序如下: /* 某年 Obfuscated C Contest 佳作选录:*/ #include < > long 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 值连小数点前共 800 位) ( 本程式录自 FAQ, 原作者未详)*/ 咋一看,这程序还挺吓人的。别慌,下面就告诉你它是如何做到的, 并且告诉你写怪异 C 程序的一些技巧。^_^ 展开化简我们知道,在 C 语言中, for 循环和 while 循环可以互相代替。 for(statement1;statement2;statement3){ statements; } 上面的 for 语句可以用下面的 while 语句来代替: statement1; while(statement2){ statements; statement3; } 而且要写怪异的 C 程序, 逗号运算符无疑是一个好的助手, 它的作用是: 从左到右依次计算各个表达式的值,并且返回最右边表达式的值。把它嵌入 for 循环中是写怪异代码的常用技巧之一。所以, 上面的程序可以展开为: #include < > /*1*/ /*2*/ long a=10000, b, c=2800, d, e, f[2801], g; /*3*/ main(){ /*4*/ while(b-c!=0){ /*5*/ f[b]=a/5; /*6*/ b++; /*7*/ } /*8*/ d=0; /*9*/ g=c*2; /*10*/ while(g!=0){ /*11*/ b=c; /*12*/ d+=f[b]*a; /*13*/ f[b]=d%--g; /*14*/ d=d/g--; /*15*/ --b; /*16*/ while(b!=0){ /*17*/ d=d*b+f[b]*a; /*18*/ f[b]=d%--g; /*19*/ d=d/g--; /*20*/ --b; /*21*/ } /*22*/ c-=14; /*23*/ printf("%.4d",e+d/a); /*24*/ e=d%a; /*25*/ d=0; /*26*/ g=c*2; /*27*/ } /*28*/ } /*29*/ 现在是不是好看一点了? 进一步化简你应该能注意到 a 的值始终是 10000 ,所以我们可以把 a 都换成 10000 。再就是,仔细观察 g ,在外层循环中,每次循环用它做除法或取余时,它总是等于 2*c-1 ,而 b 总是初始化为 c 。在内层循环中,