模拟:压位高精度
承接上一篇的十进制高精度,这是一份万进制高精度的板子
不过我想知道为啥速度变慢了
为啥
到底什么时候需要压位呢?
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("\n"); 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 }