| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 11822 人关注过本帖, 4 人收藏
标题:[原创]圆周率PI的计算(精确到几十万位)
只看楼主 加入收藏
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
结帖率:71.43%
收藏(4)
 问题点数:0 回复次数:21 
[原创]圆周率PI的计算(精确到几十万位)

//环境:VC6.0,Console Application
//原理:π=2+1/3*(2+2/5*(2+3/7*(2+...
//特点:内嵌汇编提速并扩大了计算范围
//限制:位数ws原则上没有限制但因为本
//算法的时间正比于ws的平方所以将位数
//控制在二、三十万以内较好。本人曾用
//奔Ⅳ2.6GHz算20万位,耗时10分钟左右
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<time.h>
long a=100000L;
void main()
{ FILE *fp;
long t1,t2;
char filename[40];
unsigned long c,d,e,i,j,ws;
unsigned long *f,*bb;
printf("位数=?");
scanf("%ld",&ws);
if(ws<1)return;
c=(ws+4)/05*17;
bb=f=(long*)malloc(04*c);
if(f==NULL)abort();
printf("将Pi存为: ");//提示输入数据文件名
scanf("%s",filename);//若打入NUL,则不存盘
fp=fopen(filename,"w");
if(fp==NULL)abort();
t1=time(NULL);
for(i=0;i<c-1;i++,bb++)
*bb=a/5;*bb=a/5;//这里并不错
for(e=0;c;c-=17,bb-=17,e=d%a)
{ static long group;
d=0;i=c;
j=c+c-1;
_asm mov eDI,bb
loopi:
_asm mov eax,[eDI]
_asm mul Dword ptr a
_asm mov ecx,edx
_asm mov ebx,eax
_asm mov eax,d
_asm mul dword ptr i
_asm add eax,ebx
_asm adc edx,ecx
_asm div dword ptr j
_asm mov d,eax
_asm mov [eDI],edx
_asm sub eDI,04
_asm dec dword ptr j
_asm dec dword ptr j
_asm dec dword ptr i
_asm jnz loopi
e += d/a;//这是为了避免重复计算
if(e>=100000)//这是一种糟糕情况
abort();//希望它最好不要发生
if(++group%200==0) //逢千位附近
printf( "%05lu\t",e);//显示五位
fprintf(fp,"%05lu",e);//写入磁盘
}
t2=time(NULL);
printf("%ld秒\n",t2-t1);
free(f);
fclose(fp);
}

[此贴子已经被作者于2007-4-9 17:41:55编辑过]

搜索更多相关主题的帖子: 圆周率 
2007-04-08 08:14
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
收藏
得分:0 

//自然对数的底数e的计算程序
//VC6.0,Console Application
//e=1+1(1+1/2(1+1/3(1+1/4(1+..
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
long a=100000L;
void main()
{
char filename[40];
unsigned long c,d,e,i,j,ws;
unsigned long *f,*bb;
printf("位数? ");
scanf("%ld",&ws);
if(ws<1)return;
c=(ws+4)/05*05;
bb=f=(long*)malloc(04*c);
if(f==NULL)abort();
*bb++=a/5;
for(i=1;i<c-1;i++)
*bb++=a/10;
*bb=a/10;
for(e=0;c;c-=05,bb-=05,e=d%a)
{ static long group;
d=0;i=1;j=c;
_asm mov eDI,bb
loopi:
_asm mov eax,[eDI]
_asm mul Dword ptr a
_asm mov ecx,edx
_asm mov ebx,eax
_asm mov eax,d
_asm mul dword ptr i
_asm add eax,ebx
_asm adc edx,ecx
_asm div dword ptr j
_asm mov d,eax
_asm mov [eDI],edx
_asm sub eDI,04
_asm dec dword ptr j
_asm jnz loopi
printf("%05lu\t",e+d/a);
}
free(f);
}

2007-04-09 17:58
yu_hua
Rank: 2
等 级:论坛游民
帖 子:222
专家分:95
注 册:2006-8-10
收藏
得分:0 

//下列程序虽然也能算圆周率π,但是
//仅当位数ws<=16276时,才是正确的
//事实上只要跟踪打了//////////的
//语句就会发现当ws=16000左右就已
//经“溢出”,即把大于2的31次方的
//大整数解读为负数.当ws大于16276
//时情况就变得不能容忍罢了。作为
//补救措施,可以用unsigned long以
//取代long,可正确算至32372位左右
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
void main()
{
long a=10000,c,d,e,i,j,ws,*f;
printf("位数? ");
scanf("%ld",&ws);
if(ws<1)return;
c=(ws+3)/04*14;
f=(long*)malloc(04*c);
if(f==NULL)abort();
for(i=0;i<c;i++)f[i]=a/5;
for(e=0;c;c-=14,e=d%a)
{ d=0;
for(j=c+c-1,i=c;i;i--,j-=2)
{
d=d*i+f[i]*a;//////////
f[i]=d%j;
d=d/j;
}
printf("%04d",e+d/a);
}
printf("\n");
}


[此贴子已经被作者于2007-4-10 18:19:01编辑过]

2007-04-09 18:46
intkids
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2007-4-11
收藏
得分:0 
辛苦了
2007-04-11 22:29
小鸟黑黑
Rank: 1
等 级:新手上路
帖 子:61
专家分:0
注 册:2007-7-25
收藏
得分:0 
吃个西瓜休息下 我看的头疼!厉害啊大哥

我讨厌别人叫我菜鸟,不过我的确很菜。。。
2007-08-01 12:26
fdjlglt
Rank: 1
等 级:新手上路
帖 子:52
专家分:0
注 册:2007-9-14
收藏
得分:0 

汗~~~!
不错~~!
继续努力。


2007-09-16 10:34
muse
Rank: 1
等 级:新手上路
帖 子:115
专家分:0
注 册:2007-9-13
收藏
得分:0 
我先收了。

2007-09-16 17:28
gbgame
Rank: 1
等 级:新手上路
帖 子:44
专家分:0
注 册:2007-10-27
收藏
得分:0 
强,谢谢……
2007-11-17 20:04
zmfttkl
Rank: 1
等 级:新手上路
帖 子:148
专家分:0
注 册:2007-7-1
收藏
得分:0 
顶!

2007-11-17 20:22
nuciewth
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:我爱龙龙
等 级:贵宾
威 望:104
帖 子:9786
专家分:208
注 册:2006-5-23
收藏
得分:0 
短而高效.

倚天照海花无数,流水高山心自知。
2007-11-17 20:25
快速回复:[原创]圆周率PI的计算(精确到几十万位)
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018115 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved