zoukankan      html  css  js  c++  java
  • 模拟:压位高精度

    承接上一篇的十进制高精度,这是一份万进制高精度的板子

    不过我想知道为啥速度变慢了

    为啥

    到底什么时候需要压位呢?

      1 #include <cstdio>  
      2 #include <cstring>  
      3 #include <algorithm>  
      4 
      5 
      6 using namespace std;  
      7 
      8 
      9 const int power = 1;      //每次运算的位数为10的power次方,在这里定义为了方便程序实现  
     10 const int base = 10;      //10的power次方。  
     11 
     12 
     13 //要压位的时候,只需改power 和 base即可,如压万位高精,那么power = 4, base = 10000  
     14 
     15 
     16 const int MAXL = 1001;    //数组的长度。  
     17 
     18 
     19 char a[MAXL], b[MAXL];  
     20 struct num  
     21 {  
     22     int a[MAXL];  
     23     num() { memset(a, 0, sizeof(a)); }                      //初始化  
     24     num(char *s)                                            //将一个字符串初始化为高精度数  
     25     {  
     26         memset(a, 0, sizeof(a));  
     27         int len = strlen(s);  
     28         a[0] = (len+power-1) / power;                       //数的长度  
     29         for (int i=0, t=0, w; i < len ;w *= 10, ++i)          
     30         {  
     31             if (i % power == 0) { w = 1, ++t; }  
     32             a[t] += w * (s[i]-'0');  
     33         }  
     34         //初始化数组,这里自己模拟一下,应该很容易懂的~  
     35     }  
     36     void add(int k) { if (k || a[0]) a[ ++a[0] ] = k; }     //在末尾添加一个数,除法的时候要用到  
     37     void re() { reverse(a+1, a+a[0]+1); }                   //把数反过来,除法的时候要用到  
     38     void print()                                            //打印此高精度数  
     39     {  
     40         printf("%d", a[ a[0] ]);        
     41         //先打印最高位,为了压位 或者 该高精度数为0 考虑  
     42         for (int i = a[0]-1;i > 0;--i)  
     43         printf("%0*d", power, a[i]);    
     44         //这里"%0*d", power的意思是,必须输出power位,不够则前面用0补足  
     45         printf("
    ");  
     46     }  
     47 } p,q,ans;  
     48 
     49 
     50 bool operator < (const num &p, const num &q)              //判断小于关系,除法的时候有用  
     51 {  
     52     if (p.a[0] < q.a[0]) return true;  
     53     if (p.a[0] > q.a[0]) return false;  
     54     for (int i = p.a[0];i > 0;--i)  
     55     {  
     56         if (p.a[i] != q.a[i]) return p.a[i] < q.a[i];  
     57     }  
     58     return false;  
     59 }  
     60 
     61 
     62 num operator + (const num &p, const num &q)               //加法,不用多说了吧,模拟一遍,很容易懂  
     63 {  
     64     num c;  
     65     c.a[0] = max(p.a[0], q.a[0]);  
     66     for (int i = 1;i <= c.a[0];++i)  
     67     {  
     68         c.a[i] += p.a[i] + q.a[i];  
     69         c.a[i+1] += c.a[i] / base;  
     70         c.a[i] %= base;  
     71     }  
     72     if (c.a[ c.a[0]+1 ]) ++c.a[0];  
     73     return c;  
     74 }  
     75 
     76 
     77 num operator - (const num &p, const num &q)               //减法,也不用多说,模拟一遍,很容易懂  
     78 {  
     79     num c = p;  
     80     for (int i = 1;i <= c.a[0];++i)  
     81     {  
     82         c.a[i] -= q.a[i];  
     83         if (c.a[i] < 0) { c.a[i] += base; --c.a[i+1]; }  
     84     }  
     85     while (c.a[0] > 0 && !c.a[ c.a[0] ]) --c.a[0];            
     86     //我的习惯是如果该数为0,那么他的长度也是0,方便比较大小和在末尾添加数时的判断。  
     87     return c;  
     88 }  
     89 
     90 
     91 num operator * (const num &p, const num &q)                   
     92 //乘法,还是模拟一遍。。其实高精度就是模拟人工四则运算!  
     93 {  
     94     num c;  
     95     c.a[0] = p.a[0]+q.a[0]-1;  
     96     for (int i = 1;i <= p.a[0];++i)  
     97     for (int j = 1;j <= q.a[0];++j)  
     98     {  
     99         c.a[i+j-1] += p.a[i]*q.a[j];  
    100         c.a[i+j] += c.a[i+j-1] / base;  
    101         c.a[i+j-1] %= base;  
    102     }  
    103     if (c.a[ c.a[0]+1 ]) ++c.a[0];  
    104     return c;  
    105 }  
    106 
    107 
    108 num operator / (const num &p, const num &q)               //除法,这里我稍微讲解一下  
    109 {  
    110     num x, y;  
    111     for (int i = p.a[0];i >= 1;--i)                       //从最高位开始取数  
    112     {  
    113         y.add(p.a[i]);             //把数添到末尾(最低位),这时候是高位在前,低位在后  
    114         y.re();                    //把数反过来,变为统一的存储方式:低位在前,高位在后  
    115         while ( !(y < q) )         //大于等于除数的时候,如果小于的话,其实答案上的该位就是初始的“0”  
    116             y = y - q, ++x.a[i];   //看能减几个除数,减几次,答案上该位就加几次。  
    117         y.re();                    //将数反过来,为下一次添数做准备  
    118     }  
    119     x.a[0] = p.a[0];  
    120     while (x.a[0] > 0 && !x.a[x.a[0]]) --x.a[0];  
    121     return x;  
    122 }  
    123 
    124 
    125 int main()  
    126 {  
    127     scanf("%s", a);  
    128     scanf("%s", b);  
    129     reverse(a, a+strlen(a));  
    130     reverse(b, b+strlen(b));  
    131 
    132     p = num(a), q = num(b);  
    133 /*
    134     ans = p + q;  
    135     ans.print();  
    136 
    137     ans = p - q;  
    138     ans.print();  
    139 
    140     ans = p * q;  
    141     ans.print();  
    142 */
    143     ans = p / q;  
    144     ans.print();  
    145 }  
  • 相关阅读:
    实现报表数据外置计算
    实现报表数据的可控缓存
    实现报表数据分库存储
    实现报表数据预先计算
    实现报表与算法的统一管理
    如何实现报表直接打印需求
    交叉填报表的制作
    格间计算性能提升方案
    填报脚本之轻松搞定复杂表的数据入库
    treeview_dropdown_control
  • 原文地址:https://www.cnblogs.com/aininot260/p/9635227.html
Copyright © 2011-2022 走看看