[基础数据结构]高精度加减乘除

成员介绍:

1、value:记录每一位的数值

2、size:记录有几位

3、flag: true为正数 false为负数

其他:digits: 位数大小 为(long long) 1En = 10n

           MaxS: 位数个数, 为 n


 

拆分:

一、初始化

    void clear(){
        memset(value,0,sizeof(value));
        this->size = 1;
        this->flag = 0;
        return;
    }

 


 

二、数位更新

1、进位

    void pushup(int i){
        while(this->value[i] / digits > 0){
            i++;
            this->value[i] += this->value[i-1] / digits;
            this->value[i-1] %= digits;
        }
        if(i > this->size && this->value[i]) this->size = i;  //最后处理 更新size 并且保证有值
        return;
    }

 2、退位

    void pushdown(){
        while(!this->value[this->size]) 
this->size--; }

 


 

三、赋值

    void operator = (long long x){
        this->clear();
        if(x == 0) return;
        if(x < 0) this->flag = 1,x = -x;
        this->value[1] = x;
        this->pushup(1);
        return;
    }
    void operator = (BigInt x){
        this->clear();
        this->flag = x.flag;
        this->size = x.size;
        for(int i = 1;i <= x.size;i++)
        this->value[i] = x.value[i];
        return;
    }

 


 

四、判断

1、==

    bool operator == (BigInt x) const{
        if(this->size != x.size) return false;
        if(this->flag != x.flag) return false;
        for(int i = 1;i <= x.size; i++)
            if(this->value[i] != x.value[i]) return false;
        return true;
    }

2、!=

    bool operator != (BigInt x) const{
        if(*this == x) return false;
        else return true;
    }

3、<

    bool operator < (BigInt x) const{
        if(*this == x) return false;
        if(this->flag && !x.flag) return true;
        if(!this->flag && x.flag) return false;        //正负处理 
        bool flag = false;                             //以便于取负数
        if(this->size < x.size) flag = true;
        else if(this->size > x.size) flag = false;
        else {
            for(int i = x.size;i >= 1;i--){
                if(this->value[i] < x.value[i]){       //从大到小一旦有小于就处理 
                    flag = true;
                    break;
                }
                else if(this->value[i] > x.value[i]) break; //默认为false 直接break
            }
        }
        if(this->flag) flag = !flag;                   //负数处理
        return flag;
    }

4、其他

bool operator > (BigInt x) const{
        if(x < *this) return true;
        else return false;
    }

bool operator <= (BigInt x) const{ if(*this > x) return false; else return true; }

bool operator >= (BigInt x) const{ if(*this < x) return false; else return true; }

 


 

五、加法

    BigInt operator + (BigInt x) const {
        if(!this->flag && x.flag) {
            x.flag = 0;
            return *this - x;
        }
        if(this->flag && !x.flag) {
            BigInt p = *this;
            p.flag = 0;
            return x - p;
        }                                  //关于 正+负 = 正-正 的处理
        x.size = max(this->size,x.size);
        int l = x.size;
        for(int i = 1;i <= l;i++){
            x.value[i] += this->value[i];
            x.pushup(i);                   //进位
        }
        return x;
    }

 


 

六、减法(需要'<'号)

    BigInt operator - (BigInt x) const {
        if(!this->flag && x.flag){
            x.flag = 0;
            return *this + x;
        }
        if(this->flag && !x.flag){
            x.flag = 1;
            return *this + x;
        }                                        //正-负=正+正 负-正=负+负
        BigInt p,q;
        if(*this == x) return p;                 //相等为0
        else if(*this > x) x.flag = 0;           // A-B=C 中 A>B则C>0;A<B则C<0
        else x.flag = 1;
        p = *this, q = x;
        p.flag = 0; q.flag = 0;                  //取正处理
        if(p < q) swap(p,q);
        x.size = max(p.size,q.size);             //更新大小1
        for(int i = 1;i <= x.size;i++){
            if(p.value[i] < q.value[i]){
                p.value[i] += digits;         
                p.value[i + 1] -= 1;             //借位
            }
            x.value[i] = p.value[i] - q.value[i];
        }
        x.pushdown();                            //更新大小2
        return x;
    }

 


 

七、乘法

    BigInt operator * (BigInt x) const{
        BigInt p;
        if(this->flag ^ x.flag) p.flag = 1;                                  //同为正  异为负
        for(int i = 1;i <= x.size;i++){
            for(int j = 1;j <= this->size;j++){
                p.value[i + j - 1] += x.value[i] * this->value[j];           //i+j-1要记住 
                p.pushup(i + j - 1);                                         //进位 记住在 i+j-1开始进位
            }
        }
        return p;
    }

 


 

八、除法

1、高精除以低精 (需'>')

基本思路:模拟手工除法,从高向低除求商,余数向低位进

注意:要对负数进行预处理

    BigInt operator / (long long x) const{
        BigInt p,q;
        bool flag1 = 0,flag2 = 0;
        if(x == 0) {                         //除数为0报错
            cout<<"error"<<endl;
            p = INF;
            return p;
        }
        q = *this; 
        if(x < 0){              //负数的预处理1
            flag1 = 1;
            x = -x;
        }
        if(q.flag){             //负数的预处理2
            flag2 = 1;
            q.flag = 0;
        }
        if(q < x) return p;  //不预处理2,这里会出错
        p = q;
        for(int i = p.size;i >=1; i--){
            p.value[i - 1] += (p.value[i] % x) * digits; //余数向低位进 ;不预处理1,这里会出错
            p.value[i] /= x;        //求商;不预处理1,这里会出错
        }
        p.flag = (flag1) ^ (flag2); //异或
        p.pushdown();
        return p;
    }

 


 2、高精除以高精( 需要高精'+'  '*' 高精除以低精'/'(或者另写高精除以2) )

基本思路:二分法

原理:商值 * 除数 <= 被除数 < 商值 * (除数+1)  ,证明用脚指头都会

所以商值利用二分法找到,商值范围一定处在 0 ~ 被除数 之间

商值一定处于 digits被除数位数 - 除数位数-1 ~ digits被除数位数 - 除数位数 +1 之间

简单举例子,假设digits = 10 ; 8位除以5位

最小位:10000000 / 99999 = 100 为 10, 2 = 8 - 5 -1;

最大位:   99999999 / 10000 = 9999 大约为 104 , 4 = 8 - 5 + 1;

但注意:

  • 被除数位数 - 除数位数 - 1 可能会小于0
  • 如果digits > 10时 digits被除数位数 - 除数位数+1 可能会大于 被除数
  • 负数预处理

 I、power 10处理:

    static BigInt power_digits(int x){
        BigInt p; p = 1;
        for(int i = 1;i <= x;i++)
            p *= digits;
        return p;
    }                                            //写static才可以改变内部变量

II、整体代码:

    BigInt operator / (BigInt x) const{
        BigInt l,r,mid,p,q,ansl,ansr;
        bool flag1 = 0, flag2 = 0;
        if(x == 0) {
            cout<<"error"<<endl; //除数为0 报错
            p = INF;
            return p;
        }
        q = *this;
        if(x.flag){          //负数预处理1
            flag1 = 1;
            x.flag = 0;
        }
        if(q.flag){          //负数预处理2
            flag2 = 1;
            q.flag = 0;
        }
        if(q < x) return p; //不负数预处理这里会出错
        l = power_digits(max(0, q.size - x.size -1)), 
        r = min(power_digits(q.size - x.size +1),q);  //二分法初始化
        while(l != r){               //二分法
            mid = (l + r) / 2;
            ansl = mid * x;
            ansr = ansl + x;
            if(q >= ansl && q < ansr){ //符合 商值 * 除数 <= 被除数 < 商值 * (除数+1)
                p = mid;               //若没有负数预处理这里都会出错
                p.flag = (flag1) ^ (flag2);
                return p;
            }
            else if(q <= ansl) r = mid;
            else l = mid + 1;
        }
        return p;
    }

 

九、关于常数处理

    TypeT operator ?? (long long x) const{
        BigInt p;
        p = x;
        return *this ?? p;
    }

 


 

十、关于加减乘除赋值

 

    void operator ??= (Type x) const{
        *this = *this ?? x;
    return;
    }

 

十一、输出

    int dig(int x){                          //判断位数以便于输出前面的0
        if(x == 0) return 1;
        int ans=0;
        while(x){
            ans++;
            x /= 10;
        }
        return ans;
    }
    
    void print(){
        if(this->flag) putchar('-');
        cout<<this->value[size];            //先输出头,因为头前面不应该有0
        for(int i = this->size - 1;i >= 1;i--){
            for(int j = dig(this->value[i]);j < MaxS;j++)
            putchar('0');                   //输出额外的0
            cout<<value[i];
        }
        return;
    }

 


 

十二、输入(需要'*'号)

    void scan(){
        this->clear();
        char c = getchar();
        bool flag = 0;                    //若用 this->flag 的话 若为负,则初始this为-0, 在 this = this *10 + (c^48)的时候会计算 -0 + (c^48) -> (c^48) - 0 导致this->flag = 0;
        while(c<'0' || c>'9') {
            if(c == '-') flag = 1;
            c = getchar();
        }
        while(c>='0' && c <= '9'){
            *this = *this * 10 + (c^48);
            c = getchar();
        }
        if(flag) this->flag = 1;
    }

 


 

合体:

  1 #include<bits/stdc++.h>
  2 using namespace std;
  3 
  4 const long long digits = (long long) 1E8;
  5 const int MaxS = 8;
  6 const int INF = 0x3f3f3f3f;
  7 
  8 
  9 struct BigInt{
 10     long long value[1234];
 11     int size;
 12     bool flag;
 13     
 14     void clear(){
 15         memset(value,0,sizeof(value));
 16         this->size = 1;
 17         this->flag = 0;
 18         return;
 19     }
 20     
 21     BigInt(){
 22         this->clear();
 23     }
 24     
 25     void pushup(int i){
 26         while(this->value[i] / digits > 0){
 27             i++;
 28             this->value[i] += this->value[i-1] / digits;
 29             this->value[i-1] %= digits;
 30         }
 31         if(i > this->size && this->value[i]) this->size = i;      //¸üÐÂsize ÇÒ±£Ö¤Õâ¸öµãÓÐÖµ 
 32         return;
 33     }
 34     
 35     void pushdown(){
 36         while(!this->value[this->size])
 37         this->size--;
 38     }
 39     
 40     void operator = (long long x){
 41         this->clear();
 42         if(x == 0) return;
 43         if(x < 0) this->flag = 1,x = -x;
 44         this->value[1] = x;
 45         this->pushup(1);
 46         return;
 47     }
 48     
 49     void operator = (BigInt x){
 50         this->clear();
 51         this->flag = x.flag;
 52         this->size = x.size;
 53         for(int i = 1;i <= x.size;i++)
 54         this->value[i] = x.value[i];
 55         return;
 56     }
 57     
 58     bool operator == (BigInt x) const{
 59         if(this->size != x.size) return false;
 60         if(this->flag != x.flag) return false;
 61         for(int i = 1;i <= x.size; i++)
 62             if(this->value[i] != x.value[i]) return false;
 63         return true;
 64     }
 65         
 66     bool operator == (long long x) const{
 67         BigInt p;
 68         p = x;
 69         return *this == p;
 70     }
 71 
 72     bool operator != (BigInt x) const{
 73         if(*this == x) return false;
 74         else return true;
 75     }
 76     
 77     bool operator != (long long x) const{
 78         if(*this == x) return false;
 79         else return true;
 80     }
 81     
 82     bool operator < (BigInt x) const{
 83         if(*this == x) return false;
 84         if(this->flag && !x.flag) return true;
 85         if(!this->flag && x.flag) return false;
 86         bool flag = false;
 87         if(this->size < x.size) flag = true;
 88         else if(this->size > x.size) flag = false;
 89         else {
 90             for(int i = x.size;i >= 1;i--){
 91                 if(this->value[i] < x.value[i]){
 92                     flag = true;
 93                     break;
 94                 }
 95                 else if(this->value[i] > x.value[i]) break;
 96             }
 97         }
 98         if(this->flag) flag = !flag;
 99         return flag;
100     }
101     
102     bool operator < (long long x) const{
103         BigInt p;
104         p = x;
105         return *this < p;
106     }
107     
108     bool operator > (BigInt x) const{
109         if(x < *this) return true;
110         else return false;
111     }
112     
113     bool operator > (long long x) const{
114         BigInt p;
115         p = x;
116         return *this > p;
117     }    
118     
119     bool operator <= (BigInt x) const{
120         if(*this > x) return false;
121         else return true;
122     }
123     
124     bool operator <= (long long x) const{
125         if(*this > x) return false;
126         else return true;
127     }
128     
129     bool operator >= (BigInt x) const{
130         if(*this < x) return false;
131         else return true;
132     }
133     
134     bool operator >= (long long x) const{
135         if(*this < x) return false;
136         else return true;
137     }
138     
139     BigInt operator + (BigInt x) const {
140         if(!this->flag && x.flag) {
141             x.flag = 0;
142             return *this - x;
143         }
144         if(this->flag && !x.flag) {
145             BigInt p = *this;
146             p.flag = 0;
147             return x - p;
148         }
149         x.size = max(this->size,x.size);
150         int l = x.size;
151         for(int i = 1;i <= l;i++){
152             x.value[i] += this->value[i];
153             x.pushup(i);
154         }
155         return x;
156     }
157     
158     BigInt operator + (long long x) const{
159         BigInt p;
160         p = x;
161         return *this + p;
162     }
163     
164     void operator += (BigInt x) {
165         *this = *this + x;
166         return;
167     }
168     
169     void operator += (long long x) {
170         *this = *this + x;
171         return;
172     }
173     
174     BigInt operator - (BigInt x) const {
175         if(!this->flag && x.flag){
176             x.flag = 0;
177             return *this + x;
178         }
179         if(this->flag && !x.flag){
180             x.flag = 1;
181             return *this + x;
182         }
183         BigInt p,q;
184         if(*this == x) return p;
185         else if(*this > x) x.flag = 0;
186         else x.flag = 1;
187         p = *this, q = x;
188         p.flag = 0; q.flag = 0;
189         if(p < q) swap(p,q);
190         x.size = max(p.size,q.size);
191         for(int i = 1;i <= x.size;i++){
192             if(p.value[i] < q.value[i]){
193                 p.value[i] += digits;
194                 p.value[i + 1] -= 1;
195             }
196             x.value[i] = p.value[i] - q.value[i];
197         }
198         x.pushdown();
199         return x;
200     }
201     
202     BigInt operator - (long long x) const{
203         BigInt p;
204         p = x;
205         return *this - p;
206     }
207     
208     void operator -= (BigInt x){
209         *this = *this - x;
210         return;
211     }
212     
213     void operator -= (long long x){
214         *this = *this - x;
215         return;
216     }
217     
218     BigInt operator * (BigInt x) const{
219         BigInt p;
220         p.flag = this->flag ^ x.flag;
221         for(int i = 1;i <= x.size;i++){
222             for(int j = 1;j <= this->size;j++){
223                 p.value[i + j - 1] += x.value[i] * this->value[j];          //i+j-1ÊÇÖØµã 
224                 p.pushup(i + j - 1);
225             }
226         }
227         return p;
228     }
229     
230     BigInt operator * (long long x) const{
231         BigInt p;
232         p = x;
233         return *this * p;
234     }
235     
236     void operator *= (BigInt x){
237         *this = *this * x;
238         return;
239     }
240     
241     void operator *= (long long x){
242         *this = *this * x;
243         return;
244     }
245     
246     BigInt operator / (long long x) const{
247         BigInt p,q;
248         bool flag1 = 0,flag2 = 0;
249         if(x == 0) {
250             cout<<"error"<<endl;
251             p = INF;
252             return p;
253         }
254         q = *this;
255         if(x < 0){
256             flag1 = 1;
257             x = -x;
258         }
259         if(q.flag){
260             flag2 = 1;
261             q.flag = 0;
262         }
263         if(q < x) return p;
264         p = q;
265         for(int i = p.size;i >=1; i--){
266             p.value[i - 1] += (p.value[i] % x) * digits;
267             p.value[i] /= x;
268         }
269         p.flag = (flag1) ^ (flag2);
270         p.pushdown();
271         return p;
272     }
273     
274     BigInt operator / (BigInt x) const{
275         BigInt l,r,mid,p,q,ansl,ansr;
276         bool flag1 = 0, flag2 = 0;
277         if(x == 0) {
278             cout<<"error"<<endl;
279             p = INF;
280             return p;
281         }
282         q = *this;
283         if(x.flag){
284             flag1 = 1;
285             x.flag = 0;
286         }
287         if(q.flag){
288             flag2 = 1;
289             q.flag = 0;
290         }
291         if(q < x) return p;
292         l = power_digits(max(0, q.size - x.size -1)),
293         r = min(power_digits(q.size - x.size +1),q);
294         while(l != r){
295             mid = (l + r) / 2;
296             ansl = mid * x;
297             ansr = ansl + x;
298             if(q >= ansl && q < ansr){
299                 p = mid;
300                 p.flag = (flag1) ^ (flag2);
301                 return p;
302             }
303             else if(q <= ansl) r = mid;
304             else l = mid + 1;
305         }
306         return p;
307     }
308     
309     static BigInt power_digits(int x){
310         BigInt p; p = 1;
311         for(int i = 1;i <= x;i++)
312             p *= digits;
313         return p;
314     }
315     
316     int dig(int x){
317         if(x == 0) return 1;
318         int ans = 0;
319         while(x){
320             ans++;
321             x /= 10;
322         }
323         return ans;
324     }
325     
326     void print(){
327         if(this->flag) putchar('-');
328         cout<<this->value[size];
329         for(int i = this->size - 1;i >= 1;i--){
330             for(int j = dig(this->value[i]);j < MaxS;j++)
331             putchar('0');
332             cout<<value[i];
333         }
334         return;
335     }
336     
337     void println(){
338         this->print();
339         putchar('\n');
340     }
341     
342     void scan(){
343         this->clear();
344         char c = getchar();
345         bool flag = 0;
346         while(c<'0' || c>'9') {
347             if(c == '-') flag = 1;
348             c = getchar();
349         }
350         while(c>='0' && c <= '9'){
351             *this = *this * 10 + (c^48);
352             c = getchar();
353         }
354         if(flag) this->flag = 1;
355     }
356 }que[51],de[51];

 

posted @ 2021-12-06 22:42  蒟蒻zExNocs  阅读(108)  评论(0)    收藏  举报