新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 计算机科学论坛计算机技术与应用『 C/C++编程思想 』 → 社能帮我分析一下,算圆周率的 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 3201 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 社能帮我分析一下,算圆周率的 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     waruqi 帅哥哟,离线,有人找我吗?
      
      
      等级:大一新生
      文章:5
      积分:74
      门派:XML.ORG.CN
      注册:2005/11/26

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给waruqi发送一个短消息 把waruqi加入好友 查看waruqi的个人资料 搜索waruqi在『 C/C++编程思想 』的所有贴子 引用回复这个贴子 回复这个贴子 查看waruqi的博客楼主
    发贴心情 社能帮我分析一下,算圆周率的

    **    A very easy program to compute Pi with many digits.
    **    No optimisations, no tricks, just a basic program to learn how
    **    to compute in multiprecision.  
    **
    ** Formulae:
    **
    **    Pi/4 =    arctan(1/2)+arctan(1/3)                     (Hutton 1)
    **    Pi/4 =  2*arctan(1/3)+arctan(1/7)                     (Hutton 2)
    **    Pi/4 =  4*arctan(1/5)-arctan(1/239)                   (Machin)
    **    Pi/4 = 12*arctan(1/18)+8*arctan(1/57)-5*arctan(1/239) (Gauss)
    **
    **      with arctan(x) =  x - x^3/3 + x^5/5 - ...
    **
    **    The Lehmer's measure is the sum of the inverse of the decimal
    **    logarithm of the pk in the arctan(1/pk). The more the measure
    **    is small, the more the formula is efficient.
    **    For example, with Machin's formula:
    **
    **      E = 1/log10(5)+1/log10(239) = 1.852
    **
    ** Data:
    **
    **    A big real (or multiprecision real) is defined in base B as:
    **      X = x(0) + x(1)/B^1 + ... + x(n-1)/B^(n-1)
    **      where 0<=x(i)<B
    **
    ** Results: (PentiumII, 450Mhz)
    **    
    **   Formula      :    Hutton 1  Hutton 2   Machin   Gauss
    **   Lehmer's measure:   5.418     3.280      1.852    1.786
    **
    **  1000   decimals:     0.2s      0.1s       0.06s    0.06s
    **  10000  decimals:    19.0s     11.4s       6.7s     6.4s
    **  100000 decimals:  1891.0s   1144.0s     785.0s   622.0s
    **
    ** With a little work it's possible to reduce those computation
    ** times by a factor 3 and more:
    **  
    **     => Work with double instead of long and the base B can
    **        be choosen as 10^8
    **     => During the iterations the numbers you add are smaller
    **        and smaller, take this in account in the +, *, /
    **     => In the division of y=x/d, you may precompute 1/d and
    **        avoid multiplications in the loop (only with doubles)
    **     => MaxDiv may be increased to more than 3000 with doubles
    **     => ...
    */
    #include <time.h>
    #include <stdio.h>
    #include <malloc.h>
    #include <math.h>
    long B=10000; /* Working base */
    long LB=4;    /* Log10(base)  */
    long MaxDiv=450;  /* about sqrt(2^31/B) */
    /*
    ** Set the big real x to the small integer Integer
    */
    void SetToInteger (long n, long *x, long Integer) {
      long i;
      for (i=1; i<n; i++) x[i] = 0;
      x[0] = Integer;
    }
    /*
    ** Is the big real x equal to zero ?
    */
    long IsZero (long n, long *x) {
      long i;
      for (i=0; i<n; i++)  
        if (x[i]) return 0;
     return 1;
    }
    /*
    ** Addition of big reals : x += y
    **  Like school addition with carry management
    */
    void Add (long n, long *x, long *y) {
      long carry=0, i;
      for (i=n-1; i>=0; i--) {
        x[i] += y[i]+carry;
        if (x[i]<B) carry = 0;
        else {
          carry = 1;
          x[i] -= B;
        }
      }  
    }
    /*
    ** Substraction of big reals : x -= y
    **  Like school substraction with carry management
    **  x must be greater than y
    */
    void Sub (long n, long *x, long *y) {
      long i;
      for (i=n-1; i>=0; i--) {
        x[i] -= y[i];
      if (x[i]<0) {
        if (i) { 
            x[i] += B;
            x[i-1]--;
          }
      }
      }  
    }
    /*
    ** Multiplication of the big real x by the integer q
    ** x = x*q.
    **  Like school multiplication with carry management
    */
    void Mul (long n, long *x, long q) {
      long carry=0, xi, i;
      for (i=n-1; i>=0; i--) {
        xi  = x[i]*q;  
        xi += carry;  
        if (xi>=B) {
          carry = xi/B;
          xi -= (carry*B);
        }
        else
          carry = 0;
        x[i] = xi;
     }  
    }
    /*
    ** Division of the big real x by the integer d
    ** The result is y=x/d.
    **  Like school division with carry management
    **  d is limited to MaxDiv*MaxDiv.
    */
    void Div (long n, long *x, long d, long *y) {
      long carry=0, xi, q, i;
      for (i=0; i<n; i++) {
        xi    = x[i]+carry*B;
        q     = xi/d;
        carry = xi-q*d;   
        y[i]  = q;        
      }  
    }
    /*
    ** Find the arc cotangent of the integer p = arctan (1/p)
    **  Result in the big real x (size n)
    **  buf1 and buf2 are two buffers of size n
    */
    void arccot (long p, long n, long *x, long *buf1, long *buf2) {
      long p2=p*p, k=3, sign=0;
      long *uk=buf1, *vk=buf2;
      SetToInteger (n, x, 0);
      SetToInteger (n, uk, 1); /* uk = 1/p */
      Div (n, uk, p, uk);
      Add (n, x, uk);           /* x  = uk */

      while (!IsZero(n, uk)) {
        if (p<MaxDiv)
          Div (n, uk, p2, uk);  /* One step for small p */
        else {
          Div (n, uk, p, uk);   /* Two steps for large p (see division) */
          Div (n, uk, p, uk);  
        }
        /* uk = u(k-1)/(p^2) */
        Div (n, uk, k, vk);       /* vk = uk/k  */
        if (sign) Add (n, x, vk); /* x = x+vk   */
        else Sub (n, x, vk);      /* x = x-vk   */
        k+=2;
        sign = 1-sign;
      }
    }
    /*
    ** Print the big real x
    */
    void Print (long n, long *x) {
      long i;
      printf ("%d.", x[0]);
      for (i=1; i<n; i++) {
        printf ("%.4d", x[i]);
        if (i%25==0) printf ("%8d\n", i*4);
      }
      printf ("\n");
    }
    /*
    ** Computation of the constant Pi with arctan relations
    */
    void main () {  
      clock_t endclock, startclock;
      long NbDigits=10000, NbArctan;
      long p[10], m[10];
      long size=1+NbDigits/LB, i;
      long *Pi      = (long *)malloc(size*sizeof(long));
      long *arctan  = (long *)malloc(size*sizeof(long));
      long *buffer1 = (long *)malloc(size*sizeof(long));
      long *buffer2 = (long *)malloc(size*sizeof(long));
      startclock = clock();    
      /*
      ** Formula used:
      **   
      **   Pi/4 = 12*arctan(1/18)+8*arctan(1/57)-5*arctan(1/239) (Gauss)
      */
      NbArctan = 3;
      m[0] = 12; m[1] = 8;  m[2] = -5;
      p[0] = 18; p[1] = 57; p[2] = 239;
      SetToInteger (size, Pi, 0);
      /*
      ** Computation of Pi/4 = Sum(i) [m[i]*arctan(1/p[i])]
      */
      for (i=0; i<NbArctan; i++) {
        arccot (p[i], size, arctan, buffer1, buffer2);
        Mul (size, arctan, abs(m[i]));
        if (m[i]>0) Add (size, Pi, arctan);  
        else        Sub (size, Pi, arctan);  
      }
      Mul (size, Pi, 4);
      endclock = clock ();
      Print (size, Pi);  /* Print out of Pi */
      printf ("Computation time is : %9.2f seconds\n",  
             (float)(endclock-startclock)/(float)CLOCKS_PER_SEC );
      free (Pi);
      free (arctan);
     free (buffer1);
     free (buffer2);
    }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    无限存,免费100G网络硬盘(强力推荐、绝对免费) 注册地址:(每天一次,不过可以通过删除cookies来重新注册) http://new.flashsave.com/web/get_reg.php?referid=129114

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2005/11/26 15:37:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/11/22 20:16:08

    本主题贴数1,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    62.500ms