使用c++计算高精度的π的值,其实就是一个数学的方法向c++语言转化的过程,下面将会展示:
(1)选择计算公式:选取收敛速度快的且容易朝着的计算公式是首要的一环。我们选用:
π/2=1+1/3+1/3*2/5+1/3*2/5*3/7……+1*2*3*……n/3*5*……*(2n+1)
=1+1/3(1+2/5(1+……+(n-1)/(2n-1)(1+n/(2n+1))……);
(2)确定输入的项数。要依据输入的计算位数x确定所要加的项数n,若n 太小,不能保证计算所需的精度。
若n太大,会导致作过多的无效的计算。
可以证明:式中分时第n项之后的所有余项之和Rn<an因此,只要选取n,就满足an<1/10^(x+1)即可,只要使得
lg3+lg5/2+……+lg(2n+1)/n>x+1.于是可设置对数累加实现计算到x位所需的项数n,为确保准确,算法可设置
计算位数超过x位(如5位)只打印出x位。
(3)模拟乘除综合运算。设置a数组,下标根据计算位数预设5000,必要时可增加,计算的整数值存放在a(0)中。
小数点后第i位存放在a(i)中。
数组除以2n+1,乘以n,加上1,在除以2n-1,乘n-1,加上1;……。这些数组操作设置在j(j=n,n-1,…,1)循环
中实施。按照公式实施除法操作:被除数为c,除数为d分别取2n+1,2n-1,…,3.商仍然存放在个数组元素(a(i)=c/d)
中,余数(c/d)乘10后加在后面一元素a(i+1)上,作为后一位的被除数。
按公式实施乘法操作:乘数j分别取n,n-1,……,1,乘积要注意进位,设进位数位d,则对计算的积a(i)=a(i)*j+d,
取其十位以上数作为进位数b=a(i)/10,取其个位数仍存放在原数组元素a(i)=a(i)%10中。
循环实施乘除操作完成后,按数组元素从高位到低位顺序输出,因计算位数较多,为方便查对,每一行控制打印50位,每10
个位空一格。
因为在计算中使用了数组,而且是需要开辟大片的空间进行存储,所以呢,可能会由些缓慢,但是不必着急,也是会很快的。
#include<iostream>
#include<cmath>
using namespace std;
int main()
{
float s;
int b,x,n,c,i,j,d,l,a[5000];
cout<<"欢迎您的验证,现在我们开始验证π的高精度的计算。"<<endl;
cout<<endl<<"请输入精确位数:";
cin>>x;
for(s=0,n=1;n<=5000;n++)//累加确定项数.
{
s=s+log10((2*n+1)/n);
if(s>x+1)
break;
}
for(i=0;i<=x+5;i++)
a[i]=0;
for(c=1,j=n;j>=1;j--)//按公式分布计算。
{
d=2*j+1;
for(i=0;i<=x+4;i++)//各位实施除2j+1.
{
a[i]=c/d;
c=(c%d)*10+a[i+1];
}
a[x+5]=c/d;
for(b=0,i=x+5;i>=0;i--)//各位实施乘j
{
a[i]=a[i]*j+b;
b=a[i]/10;
a[i]=a[i]%10;
}
a[0]=a[0]+1;
c=a[0];//整数加1.
}
for(b=0,i=x+5;i>=0;i--)//按公式各位乘2
{
a[i]=a[i]*2+b;
b=a[i]/10;
a[i]=a[i]%10;
}
cout<<endl<<"PI="<<a[0]<<".";//诸位输出计算结果。
for(l=10,i=1;i<=x;i++)
{
cout<<a[i];
l++;
if(l%10==0)
cout<<" ";
if(l%50==0)
cout<<endl;
}
cout<<endl;
return 0;
}
2011.9.6 15:13