|
|

楼主 |
发表于 2005-5-15 21:04:56
|
显示全部楼层
Post by welans
贴两个算pi的小程序,采用普遍的傅立叶级数展开方法,不同之处是采用的级数。速度是绝对不如superpi的,仅供参考。使用时请保留著作权信息。
程序一:
- /*************************************************************************************************************
- pi值计算程序 pi_v1
- 作者:welans @ linuxsir.cn ,2005.5. Copyright reserved
- 测试平台:Linux2.6.11-nitro2 + gcc3.4.3 @ AthlonXP1600+, 1G DDR266
- 简介:
- 计算圆周率pi到小数点后约5.5万位精度
- 根据公式 pi=3 + (1*1)/(2*3*4) * [ 3 + (3*3)/(4*5*4) *[ 3 + (5*5)/(6*7*4) * [ 3 + (7*7)/(8*9*4) * [ ... ] ] ] ]
- 每STEP计算8位,每计算8位需占用14个unsigned long long int型数组单元
-
- 本地速度评估:5000位小于1秒,50000位小于50秒( 比起super pi 差远了 :-< )
- 输入:需计算的圆周率位数,要求小于55000,不保证55000以后的精度。
- 输出:计算得到的圆周率结果保存到文件'pi.dat'中。
-
- 编译:gcc pi.c -o pi -O3
- ************************************************************************************************************/
- #include <stdio.h>
- #define MIN_LEN 8
- #define WIDTH 8
- #define STEP 14
- int ACC_CORRECT(int acc)
- {
- if(acc<MIN_LEN || acc% WIDTH)
- {
- printf("Accuracy length should be a multiple of %d and no less than %d!\n",WIDTH,MIN_LEN);
- return 0;
- }
- else return 1;
- }
- int main()
- {
- int ACCURACY_LEN; // default accuracy length.
- int MAX; // size of the array.
- unsigned long long int *a; // pointer of the array.
- unsigned long long int i,m,t,k,d,g=30000000;
-
- FILE *fp=NULL;
- if((fp=fopen("pi.dat","wb"))==NULL)
- {
- printf("Can not create 'pi.dat'!\n");
- return -1;
- }
- do
- {
- printf("Input accuracy length:");
- scanf("%d",&ACCURACY_LEN);
- }
- while( !ACC_CORRECT(ACCURACY_LEN));
- MAX=(ACCURACY_LEN*STEP)/WIDTH;
- a= malloc(MAX*sizeof(unsigned long long int));
- // main procedure for computing pi.
- for(i=0;i<MAX;i++) a[i]=30000000;
- for(m=MAX;m>0;m-=STEP)
- {
- for (t=0,i=m-1;i>0;i--)
- {
- t+=a[i]*100000000;
- k=i*(i<<4)+(i<<3);
- a[i]=t%k;
- d=(i<<1)-1;
- t=t/k*d*d;
- }
- fprintf(fp,"%.8d ",g+t/100000000);
- g=t%100000000;
- }
- //end of computing pi
- fprintf(fp,"\n");
- printf("\nResults saved to 'pi.dat'!\n");
- fclose(fp);
- free(a);
- return 0;
- }
复制代码
程序二:
- /*************************************************************************************************************
- pi值计算程序 pi_v2
- 作者:welans @ linuxsir.cn ,2005.5. Copyright reserved
- 测试平台:Linux2.6.11-nitro2 + gcc3.4.3 @ AthlonXP1600+, 1G DDR266
- 简介:
- 计算圆周率pi到小数点后约30万位精度
- 根据公式 pi=2+1/3*(2+2/5*(2+3/7*(2+4/9*(2+5/11 .....))))))
- 本地速度评估:5000位近1秒,50000位小于70秒,10万位小于5分钟。效率略低于piv1。
- 输入:需计算的圆周率位数,理论精度约30万位。
- 输出:计算得到的圆周率结果保存到文件'pi.dat'中。
-
- 编译:gcc pi.c -o pi -O3
- ************************************************************************************************************/
- #include <stdio.h>
- #define MIN_LEN 8
- #define WIDTH 8
- #define STEP 27
- int ACC_CORRECT(int acc)
- {
- if(acc<MIN_LEN || acc% WIDTH)
- {
- printf("Accuracy length should be a multiple of %d and no less than %d!\n",WIDTH,MIN_LEN);
- return 0;
- }
- else return 1;
- }
- int main()
- {
- unsigned int ACCURACY_LEN;
- unsigned int MAX ;
- unsigned long long int i,m,t,d,g=20000000;
- unsigned long long int *a;
- FILE *fp=NULL;
- if((fp=fopen("pi.dat","wb"))==NULL)
- {
- printf("Can not create 'pi.dat'!\n");
- return -1;
- }
- do
- {
- printf("Input accuracy length:");
- scanf("%d",&ACCURACY_LEN);
- }
- while(!ACC_CORRECT(ACCURACY_LEN));
- MAX=ACCURACY_LEN*STEP/WIDTH;
- a= malloc(MAX*sizeof(unsigned long long int));
- for(i=0;i<MAX;i++)a[i]=20000000;
- for(m=MAX;m>0;m-=STEP)
- {
- for (t=0,i=m-1;i>0;i--)
- {
- t+=a[i]*100000000;
- d=(i<<1)+1;
- a[i]=t%d;
- t=t/d*i;
- }
- fprintf(fp,"%.8d ",g+t/100000000);
- g=t%100000000;
- }
-
- printf("\nResult saved to file 'pi.dat'!\n");
- fclose(fp);
- free(a);
- return 0;
- }
复制代码
不错啊,大哥是自己编写的吗?好厉害。
我测试了一下,v1,50000位大概40.973s,v2同样位数大概54.671s,Athlon3000+和512M内存。什么时候把这程序改成fortran的看看。 |
|