计算π后五百位

计算π后五百位


#include<stdio.h>
#include<string.h>
#include<math.h>
int main()
{
    int a[1000]; //a[i]表示小数点后第i位数。a[0]自然就是整数部分
    memset(a,0,sizeof(a));
int sum=1,carry;
float s=0;
int cntdie;
int i,j;
int n;
int fenmu,fenzi;                      //π/2=1+1/3+1/3*2/5+1/3*2/5*3/7……+1*2*3*……n/3*5*……*(2n+1)
scanf("%d",&n);                       //1+1/3(1+2/5(1+……+(n-1)/(2n-1)(1+n/(2n+1))……);
    for(cntdie=1;cntdie<=5000;cntdie++)   //转成可以迭代的形式
   {
     s=s+log10((2*cntdie+1)/cntdie);// 只要选取cntdie,就满足acntdie<1/10^(n+1)即可,只要使得
                                                         //lg3+lg5/2+……+lg(2cntdie+1)/cntdie>n+1.
     if(s>n+1)
     break;
   }                       //cntdie记录了需要迭代的最少次数。
   for(i=cntdie;i>0;i--)  //n+3是因为算小数的时候,总会留点后位保护精度 ,我保留4位
   {
      fenmu=2*i+1;
  for(j=0;j<n+4;j++)  // 这里n+4是没算是因为a[n+5]不做考虑
  {
   a[j]=sum/fenmu;
 sum=(sum%fenmu)*10+a[j+1];
  }
  a[n+4]=sum/fenmu;               //模拟除法
  carry=0;
  fenzi=i;
  for(j=n+4;j>=0;j--)         //这还是大数乘非大数,更简单
  {
    a[j]=a[j]*fenzi+carry;
    carry=a[j]/10;
    a[j]=a[j]%10;             //更简单是因为答案是3.1415....所以不用考虑首位的进位问题
  }
  a[0]=a[0]+1;   //公式
  sum=a[0];      //其实也很自然,重新循环后就是a[0]=a[0]/fenmu;对后面没有影响
   }
    carry=0;
   for(i=n+4;i>=0;i--)
   {
     a[i]=2*a[i]+carry;
     carry=a[i]/10;
     a[i]=a[i]%10;
   }
   printf("%d.",a[0]);
   for(i=1;i<n;i++)
   printf("%d",a[i]);
   printf("%d\n",a[i]);
   return 0;
}

猜你喜欢

转载自blog.csdn.net/xigongdali/article/details/79594205