主题:[原创]写了个Machin公式算pi的程序,速度不快,算到小数点后面1万位
Rick0ne
[专家分:1490] 发布于 2007-03-28 21:35:00
公式是
pi=16arctg(1/5)-4arctg(1/239)
int main(int argc, char* argv[])
{
int const N=7200;
int const M=10000;
int const B=10000;
int const L=4;
// Machin公式 计算pi到一万位
int s[M/L];
int r1[N]={0},r2[N]={0},d1[N]={0},d2;
int r3[N]={0},r4[N]={0},d3[N]={0},d4;
int i,k,t,p=0,mp=M/L/20;
r1[0]=1;
r1[1]=3;
r3[0]=4;
printf("正在计算,请等待\n____________________\n");
for(k=0;k<M/L;++k)
{
t=r1[0]*B;
d1[0]=t/0x5;
r1[0]=t%0x5;
//
t=r3[0]*B;
d3[0]=t/0xEF;
r3[0]=t%0xEF;
s[k]=d1[0]-d3[0];
int tag=0;
for(i=1;i<N;++i)
{
t=r1[i]*B+d1[i-1];
d1[i]=t/0x19;
r1[i]=t%0x19;
t=r2[i]*B+d1[i];
d2=t/(2*i+1);
r2[i]=t%(2*i+1);
//
t=r3[i]*B+d3[i-1];
d3[i]=t/0xDF21;
r3[i]=t%0xDF21;
t=r4[i]*B+d3[i];
d4=t/(2*i+1);
r4[i]=t%(2*i+1);
if(tag)
{
s[k]+=(d2-d4);
tag=0;
}
else
{
s[k]+=(d4-d2);
tag=1;
}
}
if(p==mp)
{
printf(">");
p=0;
}
else
p++;
}
for(i=M/L-1;i>=0;i--)
{
while(s[i]>=B)
{
s[i-1]++;
s[i]-=B;
}
while(s[i]<0)
{
s[i-1]--;
s[i]+=B;
}
}
printf("\npi=3.\n");
for(i=0;i<M/L;++i)
printf("%04d",s[i]);
return 0;
}
复杂度是O(M*N),N是计算的项数,M是要精确到的位数,它们的关系要解个不等式。在Release下编译速度快一点,可能的优化是/和%运算的重复。
结果就自己试试,不帖出来了,经检查,发现最后两位不准确,公式本身决定的,前面都抽样检查过,应该没问题。
回复列表 (共32个回复)
沙发
forjane [专家分:5670] 发布于 2007-03-29 08:25:00
唉,数学不好,看着晕晕的~
板凳
雨中飞燕 [专家分:18980] 发布于 2007-03-29 09:10:00
真厉害。。。>_<
3 楼
Rick0ne [专家分:1490] 发布于 2007-03-29 12:28:00
[quote]唉,数学不好,看着晕晕的~[/quote]
我自己都觉得这样的代码没办法弄得很容易懂,命名啊,注释啊,都显得苍白。也不是我故意写成这样,没办法,那个rx[]是余数,dx[]是商,依据还是那个公式,再加上级数展开。
4 楼
zhangmou [专家分:14200] 发布于 2007-03-29 15:05:00
//油箱发现有一个。贴上比较一下
#include<iostream.h>
void main()
{
const int ARRSIZE=10010,DISPCNT=10002;
static char x[ARRSIZE],z[ARRSIZE];
int i,a(1),b(3),c,d,Run(1),Cnt(0);
x[1]=2;z[1]=2;
while(Run&&(++Cnt<20000000))
{
//z*=a;
d=0;
for(i=ARRSIZE-1;i>0;i--)
{
c=z[i]*a+d;
z[i]=c%10;
d=c/10;
}
//z/=b;
d=0;
for(i=0;i<ARRSIZE;i++)
{
c=z[i]+d*10;
z[i]=c/d;
d=c%b;
}
//x+=z;
Run=0;
for(i=ARRSIZE-1;i>0;i--)
{
c=x[i]+z[i];
x[i]=c%10;
x[i-1]+=c/10;
Run/=z[i];
}
a++;
b+=2;
}
cout<<"计算了次数为:"<<Cnt<<endl;
d=0;
for(i=2;i<DISPCNT;i++)
{
cout<<(int)x[i];
d++;
if((d%50)==0){cout<<endl;continue;}
if((d%10)==0)cout<<' ';
}
}
5 楼
Rick0ne [专家分:1490] 发布于 2007-03-29 15:23:00
看到过弄这个程序的说明,是另外一个公式,我不知道它的余项,所以没这么做。Machin公式应该是较快算法里最简单的一个,如果要更快的速度,一个高效的高精运算库是少不了的。
6 楼
Rick0ne [专家分:1490] 发布于 2007-03-29 15:24:00
刚写的,有公式的实现方法。
[url=http://blog.programfan.com/article.asp?id=24388]简单方法算pi和e,计算到小数点后面一万位
http://blog.programfan.com/article.asp?id=24388[/url]
7 楼
forjane [专家分:5670] 发布于 2007-03-29 15:30:00
不错
8 楼
euc [专家分:4310] 发布于 2007-03-29 16:14:00
???怎么把arctan()变成级数呢?
9 楼
雨中飞燕 [专家分:18980] 发布于 2007-03-29 16:26:00
用泰勒级数展开
10 楼
Rick0ne [专家分:1490] 发布于 2007-03-29 17:44:00
4楼的程序,我怎么算了N久,然后出错了啊~~
我来回复