一道高精度计算题

网友Mutalisk给的一道题目,
计算 (1+2^0)*(1+2^1)*(1+2^2)…(1+2^32)

今晚赶回家了,花了几十分钟写好了代码,计算结果和Mutalisk的一样。运行时间为10毫秒,当然,是在我PIII 900Mhz的机子上,基本上一闪就出结果。
我的结果是160位,
41900194778866063098
69616409977680717118
75372548418310142014
25167533420258842344
35351687855236795051
88646940175563375578
68147135401121187966
16074978167792968750

源代码下载
 


内容:

  1. #include <windows.h>  
  2. #include <stdio.h>  
  3. #include <string.h>  
  4. #include <stdlib.h>  
  5.   
  6. struct big_number{  
  7.     int d[64];  // 4*64 256λ  
  8.     int len;  
  9. }exp2[40], ans;  
  10.   
  11.   
  12. void print( big_number & b )  
  13. {  
  14.     int i, j;  
  15.     for( i=b.len-1; i>=0; i-- ){  
  16.         for( j=1000; j>=1; j/=10 )  
  17.             if( !(i==b.len-1 && j>1 && b.d[i]<j ) )  
  18.                 printf("%d", (b.d[i]/j)%10 );  
  19.     }  
  20. }  
  21.   
  22. void mul( big_number & b, int a )  
  23. {  
  24.     int i, r;  
  25.     r = 0;  
  26.     for( i=0; i<b.len; i++ ){  
  27.         r = r + b.d[i] * a;  
  28.         b.d[i] = r % 10000;  
  29.         r /= 10000;  
  30.     }  
  31.     //ÏÂÃæÑ­»·¿ÉÒÔÓÅ»¯  
  32.     while( r>0 ){  
  33.         b.d[b.len++] = r % 10000;  
  34.         r /= 10000;  
  35.     }  
  36. }  
  37.   
  38. void mul2( big_number &a, big_number &b )  
  39. {  
  40.     int i, j, k, p, r;  
  41.     big_number c;   //result  
  42.     memset( &c, 0, sizeof(c) );  
  43.     for( i=0; i<b.len; i++ ){  
  44.         p = b.d[i];  
  45.         for( k=0, j=i, r=0; k<a.len; k++, j++ ){  
  46.             r = r + a.d[k] * p + c.d[j];  
  47.             c.d[j] = r % 10000;  
  48.             r /= 10000;  
  49.         }  
  50.         //ÏÂÃæÑ­»·¿ÉÒÔÓÅ»¯È¥µô  
  51.         while( r>0 ){  
  52.             r = c.d[j] + r;  
  53.             c.d[j] = r % 10000;  
  54.             r /= 10000;  
  55.             j ++;  
  56.         }  
  57.         c.len = j;  
  58.     }  
  59.     a = c;  
  60. }  
  61.   
  62. void add( big_number & a, big_number & b )  
  63. {  
  64.     int i, r;  
  65.     r = 0;  
  66.     a.len = a.len<b.len ? b.len : a.len;  
  67.     for( i=0; i<a.len; i++ ){  
  68.         r = r + a.d[i] + b.d[i];  
  69.         a.d[i] = r % 10000;  
  70.         r /= 10000;  
  71.     }  
  72.     //ÏÂÃæÒ»²œ¿ÉÒÔÓÅ»¯  
  73.     while( r>0 ){  
  74.         a.d[a.len++] = r % 10000;  
  75.         r /= 10000;  
  76.     }  
  77. }  
  78.   
  79. int is_bigger( big_number & a, big_number & b )  
  80. {  
  81.     if( a.len > b.len )  
  82.         return 1;  
  83.     else if( a.len < b.len )  
  84.         return 0;  
  85.     int i;  
  86.     for( i=a.len-1; i>=0; i-- ){  
  87.         if( a.d[i] > b.d[i] )  
  88.             return 1;  
  89.         else if( a.d[i] < b.d[i] )  
  90.             return 0;  
  91.     }  
  92.     return 0;  
  93. }  
  94.   
  95. //ŒÆËã2µÄ·œ  
  96. void prepare()  
  97. {  
  98.     int i,j;  
  99.     memset( &exp2[0], 0, sizeof(big_number) );  
  100.     exp2[0].d[0] = 1;  
  101.     exp2[0].len = 1;  
  102.     for( i=1; i<=32; i++ ){  
  103.         exp2[i] = exp2[i-1];  
  104.         add( exp2[i], exp2[i-1] ); //ŒÓ·š±È³Ë·š¿ì  
  105.         //mul( exp2[i], 2 );  
  106.     }  
  107. }  
  108.   
  109. //ŒÆËã (1+2^0)*(1+2^1)*(1+2^2)...(1+2^32)  
  110. void work()  
  111. {  
  112.     int i;  
  113.     big_number t;  
  114.     memset( &ans, 0, sizeof(ans) );  
  115.     memset( &t, 0, sizeof(t) );  
  116.     t.d[0] = 1;  
  117.     t.len = 1;  
  118.     ans.d[0] = 1;  
  119.     ans.len = 1;  
  120.     for( i=0; i<=32; i++ ){  
  121.         add( exp2[i], t );  // + 1  
  122.         mul2( ans, exp2[i] );  
  123.     }  
  124.     print( ans );  
  125. }  
  126.   
  127. int main()  
  128. {  
  129.     int n=GetTickCount();  
  130.     prepare();  
  131.     work();  
  132.     printf("\nTime used: %dmm\n", GetTickCount()-n );  
  133.     system("pause");  
  134.     return 0;  
  135. }  

一道高精度计算题》有16个想法

  1. Mutalisk

    哈哈,还是你的方法好啊。家里的机器的浏览器好像有问题,你的文章都看不全,只能看一小半

    回复
  2. Mutalisk

    比起你的来,我的那个就太冗余了,400+行代码。

    虽然也只用了16ms。但是毕竟我的机器比较好

    回复
  3. me

    struct big_number{
    int d[64]; // 4*64 256位
    int len;
    }exp2[40], ans
    从这里可以看出ans最大表示2^256-1的数。但是(1+2^0)*(1+2^1)*(1+2^2)…(1+2^32) > (2^0)*(2^1)*(2^2)…(2^32)=2^(32*33/2)=2^528.

    回复
  4. weeklybuilds

    阿阿。菜鸟我也边学边写个python的,看来结果和你一样的,写对了

    hp@debian:~/Desktop$ time python ./aa.py
    4190019477886606309869616409977680717118753725484183101420142516753342025884234435351687855236795051886469401755633755786814713540112118796616074978167792968750

    real 0m0.019s
    user 0m0.016s
    sys 0m0.004s

    回复

回复 SONIC3D 取消回复

您的邮箱地址不会被公开。 必填项已用 * 标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据