[ C++ 快速高精度模板 ] [ BigN类 ] 大整数类 高精度 模板 BigInt FFT 快速傅里叶变换

【原创 转载请注明】瞎写的,如果代码有错,或者各位大佬有什么意见建议,望不吝赐教

更新日志:

  对于规模较小的整数乘法使用$$O(n^2)$$方法,提高速度

  modify()和operator[]的bug修正

  除法速度提升

  修正了除法崩溃的问题

  修正了除数为零崩溃的问题

 

  1 /**
  2   * BigN Beata v1.3.1
  3   * By: Nathaniel
  4   * 13th,Dec,2017
  5  **/
  6 
  7 //This file provides four operation for big-intgers
  8 //You can use class 'BigN' to define a variable.
  9 //Follow operators are available
 10 //+ - * / % = += -= *= /= %= > < >= <= == !=
 11 //these operators can used between BigN and BigN or BigN and int.
 12 
 13 //You can use function print() to print a BigN to stdout.
 14 //printn() will print a '\n' at the end.
 15 //Function getstr() and str() will return a std::string-type string.
 16 
 17 //IN SAFE MODE, you can access k-th digit, from 0-th high digits, by [].
 18 //Or you can also modify x-th digit by modify(x,y).
 19 
 20 //In this template, multipy operator is implicated by fast_Fourier_transform,
 21 //Which can calculate convolution of to n-vectors in O(nlogn) time.
 22 //When number is small, this code still use O(n^2) algorithm.
 23 //and divide operator is implicated by dichotomy.
 24 
 25 //-O2 or -O3 optimize option is recomended.
 26 
 27 //**********************************************************************//
 28 //If you delete the follow definition,the calc speed will improve
 29 //but when number become huge, especially over 2000000 digits,
 30 //it may NOT work correctly.
 31 //So, to make sure that you answer is correct, do NOT delete this line.
 32 
 33     //#define SAFE_CALC_MODE
 34 
 35 //**********************************************************************//
 36 
 37 #include <iostream>
 38 #include <algorithm>
 39 #include <cmath>
 40 #include <cstring>
 41 #include <cstdio>
 42 #include <cstdlib>
 43 #include <ctime>
 44 #include <string>
 45 #include <vector>
 46 #include <complex>
 47 
 48 const double _pi=acos(-1);
 49 
 50 class _fast_Fourier_transform
 51 {
 52     typedef std::complex<double> Cmplx;
 53     typedef std::vector<Cmplx>    E;
 54     typedef std::vector<int> Vec;
 55     private:
 56     int _n,_m,_N;
 57     Vec R;
 58 
 59     //butterfly operation
 60     inline void    Expand(int temp)
 61     {
 62         int    L=0; for(_N=1;_N<=temp;_N<<=1,L++);
 63         R.resize(_N+1);
 64         for(int i=0;i<_N;++i) R[i]=R[i>>1]>>1|(i&1)<<(L-1);
 65         return ;
 66     }
 67 
 68     //Fast Fourier Transform
 69     void    FFT(E& A,int f)
 70     {
 71         for(int i=0;i<_N;++i) if(i<R[i]) swap(A[i],A[R[i]]);
 72         for(int i=1;i<_N;i<<=1)
 73         {
 74             Cmplx wn(cos(_pi/i),f*sin(_pi/i));
 75             for(int j=0;j<_N;j+=i<<1)
 76             {
 77                 Cmplx w(1,0);
 78                 for(int k=0;k<i;++k,w*=wn)
 79                 {
 80                     Cmplx x=A[j+k],y=w*A[i+j+k];
 81                     A[j+k]=x+y; A[i+j+k]=x-y;
 82                 }
 83             }
 84         } return ;
 85     }
 86 
 87     inline Vec Mul(E& A,E& B)
 88     {
 89         Expand(_n+_m); A.resize(_N+1); B.resize(_N+1);
 90         FFT(A,1); FFT(B,1);//DFT
 91         for(int i=0;i<=_N;++i) A[i]*=B[i];//MUL
 92         FFT(A,-1);//IDFT
 93         std::vector<int> vec;
 94         for(int i=0;i<_n+_m-1;++i)
 95             vec.push_back((int)(A[i].real()/_N+0.5));
 96                     //fix deviation
 97         return vec;
 98     }
 99         
100 
101 
102     public:
103     inline Vec multi(Vec& AA,Vec& BB)
104     {
105         E A,B;
106         _n=AA.size(); _m=BB.size();
107         //turn two vectors to complex
108         A.resize(_n); B.resize(_m);
109         for(int i=0;i<_n;++i) A[i]=AA[i];
110         for(int i=0;i<_m;++i) B[i]=BB[i];
111         return Mul(A,B);
112     }
113 };
114 
115 class    _normal_mul
116 {
117     //O(n^2) multiply
118     typedef std::vector<int> Vec;
119     private:
120     inline Vec mul(Vec& A,Vec& B)
121     {
122         Vec vec; int _n,_m;
123         _n=(int)A.size(),_m=(int)B.size();
124         vec.resize(_n+_m);
125         for(int i=0;i<_n;++i) for(int j=0;j<_m;++j)
126             vec[i+j]+=A[i]*B[j];
127         return vec;
128     }
129     public:
130     inline Vec multi(Vec& AA,Vec& BB) { return mul(AA,BB); }
131 };
132 
133 #ifndef SAFE_CALC_MODE
134 #define DIGITS 1000
135 #else
136 #define DIGITS 10
137 #endif
138 
139 class Divide_By_Zero_Error { };
140 
141 class _data_container_of_BigN
142 {
143     private:
144     bool sym;//0 positive,1 negetive
145     unsigned int length;//total length of the number
146     std::vector<int> vec;//vector of data
147     
148     public:
149     typedef _data_container_of_BigN _this_class;
150     inline void    _set_zero()
151         { sym=0; length=1; vec.clear(); vec.push_back(0); }
152     _data_container_of_BigN() { _set_zero();}
153     _data_container_of_BigN(int x)
154     {
155         //turn int to BigN
156         _set_zero();
157         if(x) vec.pop_back();
158         if(x<0) sym=true,x=-x;
159         while(x)
160         {
161             vec.push_back(x%DIGITS);
162             x/=DIGITS;
163         }
164         update_length();
165     }
166     _data_container_of_BigN(const char* str)
167     {
168         int    _n=strlen(str),data=0,base=1,t=0;
169         vec.clear(); if(str[0]=='-') sym=true,t=1;
170         for(int i=_n-1; i>=t; --i)
171         {
172             data=data+(str[i]-48)*base;
173 #ifndef SAFE_CALC_MODE
174             if((_n-i)%3==0)
175 #endif
176             {
177                 vec.push_back(data),data=0,base=1;
178                 continue;
179             }
180             base*=10;
181         }
182         vec.push_back(data);
183         update_length();
184     }
185 
186     inline _this_class operator=(const char* str)
187     {
188         //turn char* to BigN
189         int    _n=strlen(str),data=0,base=1,t=0;
190         vec.clear(); if(str[0]=='-') sym=true,t=1;
191         for(int i=_n-1; i>=t; --i)
192         {
193             data=data+(str[i]-48)*base;
194 #ifndef SAFE_CALC_MODE
195             if((_n-i)%3==0)
196 #endif
197             {
198                 vec.push_back(data),data=0,base=1;
199                 continue;
200             }
201             base*=10;
202         }
203         vec.push_back(data);
204         update_length();
205         return *this;
206     }
207 
208     inline _this_class operator =(int x)
209     {
210         //turn int to BigN
211         _set_zero();
212         if(x) vec.pop_back();
213         if(x<0) sym=true,x=-x;
214         while(x)
215         {
216             vec.push_back(x%DIGITS);
217             x/=DIGITS;
218         }
219         update_length();
220         return *this;
221     }
222 
223     inline _this_class operator -()
224     {
225         _this_class C=*this;
226         C.sym=!C.sym;
227         return C;
228     }
229 
230 
231     inline int&    operator[](int x) { return vec[x]; }
232 
233     inline bool    is_positive() { return !sym; }
234     inline bool    is_negetive() { return sym; }
235 
236     //Fix -0 to 0
237     inline void    fix_zero()
238     { if(sym && length==1 && vec[0]==0) sym=!sym; }
239 
240     //get k-th digit
241     inline int    getkth(const int x)
242     {
243         if(x>=(int)length) return -1;
244         return vec[length-x-1];
245     }
246     //Modify
247     inline bool    modify(const int x,const int y)
248     {
249         if(x>=(int)length) return false;
250         vec[length-x-1]=y; update_length(); return true;
251     }
252         
253 
254     inline _this_class operator+(_this_class& B)
255     {
256         if(!sym && !B.sym) return positive_add(B);
257         if(sym && B.sym) return -positive_add(B);
258         if(sym && !B.sym)
259         {
260             if(compare_abs(B)>0) return -positive_minus(B);
261             return B.positive_minus(*this);
262         }
263         if(compare_abs(B)>0) return positive_minus(B);
264         return -B.positive_minus(*this);
265     }
266 
267     inline _this_class operator-(_this_class& B)
268     {
269         if(!sym && !B.sym)
270         {
271             if(compare_abs(B)>0) return positive_minus(B);
272             return -B.positive_minus(*this);
273         }
274         if(sym && B.sym)
275         {
276             if(compare_abs(B)>0) return -positive_minus(B);
277             return B.positive_minus(*this);
278         }
279         if(!sym && B.sym) return positive_add(B);
280         return -B.positive_add(*this);
281     }
282 
283     inline _this_class operator*(_this_class& B)
284     {
285         return sym^B.sym?-positive_muliply(B):
286             positive_muliply(B);
287     }
288 
289     inline _this_class operator/(_this_class& B)
290     {
291         try
292         {
293             return sym^B.sym?-positive_divide(B):
294             positive_divide(B);
295         }catch(...)
296         {
297             std::cerr << std::endl;
298             std::cerr << "\tError: Division is 0." << std::endl;
299         }
300         return B;
301     }
302 
303     inline _this_class operator%(_this_class& B)
304     {
305         try
306         {
307             return sym^B.sym?-positive_mod(B):
308             positive_mod(B);
309         }catch(...)
310         {
311             std::cerr << std::endl;
312             std::cerr << "\tError: Division is 0." << std::endl;
313         }
314         return *this;
315     }
316 
317     inline _this_class operator+(int B){ _this_class t=B; return *this+t; }
318     inline _this_class operator-(int B){ _this_class t=B; return *this-t; }
319     inline _this_class operator*(int B){ _this_class t=B; return *this*t; }
320     inline _this_class operator/(int B){ _this_class t=B; return *this/t; }
321     inline _this_class operator%(int B){ _this_class t=B; return *this%t; }
322 
323     inline _this_class operator+=(_this_class& B) { return *this=*this+B; }
324     inline _this_class operator-=(_this_class& B) { return *this=*this-B; }
325     inline _this_class operator*=(_this_class& B) { return *this=*this*B; }
326     inline _this_class operator/=(_this_class& B) { return *this=*this/B; }
327     inline _this_class operator%=(_this_class& B) { return *this=*this%B; }
328     inline _this_class operator+=(int B) { return *this=*this+B; }
329     inline _this_class operator-=(int B) { return *this=*this-B; }
330     inline _this_class operator*=(int B) { return *this=*this*B; }
331     inline _this_class operator/=(int B) { return *this=*this/B; }
332     inline _this_class operator%=(int B) { return *this=*this%B; }
333 
334     //Print func will print the number to stdout in casual format
335     void    print()
336     {
337         if(is_negetive()) printf("-");
338 #ifdef SAFE_CALC_MODE
339         for(int i=vec.size()-1;i>=0;--i)
340             printf("%d",vec[i]);
341 #else
342         printf("%d",vec[vec.size()-1]);
343         for(int i=vec.size()-2;i>=0;--i)
344             printf("%03d",vec[i]);
345 #endif
346         return ;
347     }
348     //Print func will print the number to 'str' in casual format
349     void    print_to_str(std::string& str)
350     {
351         str="";
352         char tempstr[4];
353         if(is_negetive()) str="-";
354 #ifdef SAFE_CALC_MODE
355         for(int i=vec.size()-1;i>=0;--i)
356             sprintf(tempstr,"%d",vec[i]),
357                 str+=tempstr;
358 #else
359         sprintf(tempstr,"%d",vec[vec.size()-1]);
360         str+=tempstr;
361         for(int i=vec.size()-2;i>=0;--i)
362             sprintf(tempstr,"%03d",vec[i]),
363                 str+=tempstr;
364 #endif
365         return ;
366     }
367 
368     inline unsigned int size() { return vec.size(); }
369 
370     /*
371         *     this func
372         *     returns 1 if *this>B
373         *     returns -1 if *this<B
374         *     return 0 if *this==B
375     */
376     inline int    compare_abs(_this_class& B)
377     {
378         if(length>B.length) return 1;
379         if(length<B.length) return -1;
380         for(int i=vec.size()-1;i>=0;--i)
381             if(vec[i]>B[i])return 1;
382             else if(vec[i]<B[i]) return -1;
383         return 0;
384     }
385 
386     protected:
387 
388     inline void    clear_zero()
389     //This func deletes leading zero
390     {
391         while(!vec[vec.size()-1] && vec.size()!=1)
392             vec.pop_back();
393         return ;
394     }
395 
396     /***************************************************************/
397     //CALL THIS FUNCTION AFTER EVERY OPERATION TO MAKE ANSWER CORRECT
398 #ifndef SAFE_CALC_MODE
399     inline void    update_length()
400     //fixup length and leading zero
401     {
402         clear_zero();
403         if(vec.size()==1 && vec[0]==0) length=1;
404         else if(vec[vec.size()-1]/100)length=vec.size()*3;
405         else if(vec[vec.size()-1]/10)length=vec.size()*3-1;
406         else length=vec.size()*3-2;
407         return ;
408     }
409 #else
410     //fixup length and leading zero
411     inline void    update_length()
412     {
413         clear_zero();
414         length=vec.size(); return ;
415     }
416 #endif
417     /***************************************************************/
418 
419     //carry the vec
420     //notice: call update_length() after calling this func
421     inline void    Go_up()
422     {
423         int t=vec.size();
424         for(int i=0;i<t-1;++i)
425         {
426             vec[i+1]+=vec[i]/DIGITS;
427             vec[i]%=DIGITS;
428         }
429         while(vec[t-1]>=DIGITS)
430             vec.push_back(vec[t-1]/DIGITS),vec[t-1]%=DIGITS,t++;
431         return ;
432     }
433 
434     //resize the vector
435     inline void    resize(int x) { vec.resize(x); }
436 
437     inline int    get_quotient(_this_class& R,_this_class& B,
438             _this_class* Map)
439     //This func get a quotient for divide operator by dichotomy
440     {
441         if(R.compare_abs(B)<0) return 0;
442         int l=0,r=DIGITS,mid;
443         while(l<r-1)
444         {
445             mid=l+((r-l)>>1);
446             if(mid && Map[mid].size()==1 && Map[mid][0]==0)
447                 Map[mid]=B*mid;
448             int t=R.compare_abs(Map[mid]);
449             if(t>0)l=mid;
450             else if(t<0)r=mid;
451             else { l=mid; break; }
452         }
453         if(mid && Map[l].size()==1 && Map[l][0]==0) Map[l]=B*l;
454         R=R-Map[l];
455         return l;
456     }
457 
458 
459     private:
460 
461     inline _this_class positive_add(_this_class& B)
462     //This func returns Abs(*this)+Abs(B)
463     //calling this func must garantee '*this' and 'B' are both positive
464     {    
465         _this_class C;//ans
466         bool _Longer_vec;
467 
468         if(vec.size()>B.size())    _Longer_vec=1;
469         else            _Longer_vec=0;
470 
471         //if B is shorter
472         if(_Longer_vec)
473         {
474             C.resize(vec.size()+1);
475             //add shorter digits first
476             for(int i=0;i<(int)B.size();++i)
477             {
478                 C[i+1]=(C[i]+vec[i]+B[i])/DIGITS;
479                 C[i]=(C[i]+vec[i]+B[i])%DIGITS;
480             }//each saves 3 digits
481 
482             //calc rest digits
483             for(int i=B.size();i<(int)vec.size();++i)
484             {
485                 C[i+1]=(C[i]+vec[i])/DIGITS;
486                 C[i]=(C[i]+vec[i])%DIGITS;
487             }
488         }
489         //if B is longer
490         else 
491         {
492             C.resize(B.size()+1);
493             //add shorter digits first
494             for(int i=0;i<(int)vec.size();++i)
495             {
496                 C[i+1]=(C[i]+vec[i]+B[i])/DIGITS;
497                 C[i]=(C[i]+vec[i]+B[i])%DIGITS;
498             }//each saves 3 digits
499 
500             //calc rest digits
501             for(int i=vec.size();i<(int)B.size();++i)
502             {
503                 C[i+1]=(C[i]+B[i])/DIGITS;
504                 C[i]=(C[i]+B[i])%DIGITS;
505             }
506         }
507         C.update_length();
508         return C;
509     }
510 
511     inline _this_class positive_minus(_this_class& B) 
512     //This func returns Abs(*this)-Abs(B)
513     //calling this func must garantee '*this > B'
514     {
515         _this_class C;//ans
516         C.resize(vec.size());
517         //calc first B.size() digits
518         for(int i=0;i<(int)B.size();++i)
519         {
520             if(vec[i]+C[i]<B[i])C[i]+=DIGITS+vec[i]-B[i],C[i+1]--;
521             else C[i]+=vec[i]-B[i];
522         }
523         //copy the rest digits
524         for(int i=B.size();i<(int)vec.size();++i)
525             C[i]+=vec[i];
526         C.update_length();
527         return C;
528     }
529 
530     inline _this_class positive_muliply(_this_class& B)
531     //This func returns Abs(*this)*Abs(B)
532     {
533         _this_class C=*this;
534 
535         double temp=log(vec.size()+B.size())/log(2);
536 
537         if((vec.size()+B.size())*temp<vec.size()*B.size())
538         //Using fast Fourier transform if (n+m)log(n+m)<n*m
539         //to speed mul operation when data become huge
540         {
541             _fast_Fourier_transform F;
542             C.vec=F.multi(C.vec,B.vec);
543         }
544         else
545         //Using normal O(n*m) algorithm when n,m is small
546         {
547             _normal_mul F;
548             if(vec.size()<B.size())C.vec=F.multi(C.vec,B.vec);
549             else C.vec=F.multi(B.vec,C.vec);
550         }
551         
552         C.Go_up();
553         C.update_length();
554         return C;
555     }
556 
557     inline _this_class positive_divide(_this_class& B)
558     //This func returns Abs(*this)/Abs(B)
559     {
560         if(B.length==1 && B.vec[0]==0) throw Divide_By_Zero_Error();
561         _this_class C;
562         _this_class r;//Remainder
563 
564         _this_class Map[DIGITS+2];
565         //save B*x to save time.
566 
567         //if dividend is less return 0
568         if(compare_abs(B)<0) return C;
569 
570         //if dividend is equal to divisor return 1
571         if(compare_abs(B)==0) { C[0]=1; return C; }
572 
573         C.resize(vec.size());
574         r.resize(B.size());
575         for(int i=B.size()-2;i>=0;--i)
576             r[i]=vec[vec.size()-B.size()+1+i];
577         r.update_length();
578 
579         for(int i=vec.size()-B.size();i>=0;--i)
580         {
581             r*=DIGITS; r[0]+=vec[i]; r.update_length();
582             //dichotomy
583             int t=get_quotient(r,B,Map);
584             C[i]=t;
585         }
586         C.update_length();
587         return C;
588     }
589 
590     inline _this_class positive_mod(_this_class& B)
591     //This func returns Abs(*this)%Abs(B)
592     {
593         if(B.length==1 && B.vec[0]==0) throw Divide_By_Zero_Error();
594         _this_class r;//Remainder
595 
596         _this_class Map[DIGITS+2];
597         //save B*x to save time.
598 
599         //if dividend is less return vec
600         if(compare_abs(B)<0) return *this;
601 
602         //if dividend is equal to divisor return 1
603         if(compare_abs(B)==0) return r;
604 
605         r.resize(B.size());
606         for(int i=B.size()-2;i>=0;--i)
607             r[i]=vec[vec.size()-B.size()+1+i];
608         r.update_length();
609 
610         for(int i=vec.size()-B.size();i>=0;--i)
611         {
612             r*=DIGITS; r[0]+=vec[i]; r.update_length();
613             //dichotomy
614             get_quotient(r,B,Map);
615         }
616         return r;
617     }
618 };
619 
620 //Use This Class in your program.
621 class BigN
622 {
623     public:
624 #ifdef    SAFE_CALC_MODE
625     //You may NOT modify the digits directly.
626     //if number has NO x-th number, function will return -1
627     inline int    operator[](const int x) { return _data.getkth(x); }
628     //This Func change x-th digit to y.(start from 0th,high digit)
629     //Returns false for failure, true for success.
630     inline bool    modify(const int x,const int y)
631     { return _data.modify(x,y); }
632 #endif
633 
634     //Fix -0 to 0
635     inline void    Fix_zero() { _data.fix_zero(); }
636     
637     inline BigN    operator = (const int B)
638     { _data=B; Fix_zero(); return *this;}
639     inline BigN    operator = (const char* B)
640     { _data=B; Fix_zero(); return *this;}
641 
642     inline BigN    operator + (BigN B)
643     { B._data=_data+B._data; B.Fix_zero(); return B; }
644     inline BigN    operator - (BigN B)
645     { B._data=_data-B._data; B.Fix_zero(); return B; }
646     inline BigN    operator * (BigN B)
647     { B._data=_data*B._data; B.Fix_zero(); return B; }
648     inline BigN    operator / (BigN B)
649     { B._data=_data/B._data; B.Fix_zero(); return B; }
650     inline BigN    operator % (BigN B)
651     { B._data=_data%B._data; B.Fix_zero(); return B; }
652     inline BigN    operator + (int B)
653     { BigN C=B; C._data=_data+C._data; C.Fix_zero(); return C; }
654     inline BigN    operator - (int B)
655     { BigN C=B; C._data=_data-C._data; C.Fix_zero(); return C; }
656     inline BigN    operator * (int B)
657     { BigN C=B; C._data=_data*C._data; C.Fix_zero(); return C; }
658     inline BigN    operator / (int B)
659     { BigN C=B; C._data=_data/C._data; C.Fix_zero(); return C; }
660     inline BigN    operator % (int B)
661      { BigN C=B; C._data=_data%C._data; C.Fix_zero(); return C; }
662     inline BigN operator+=(BigN B)
663     { _data+=B._data; Fix_zero(); return *this; }
664     inline BigN operator-=(BigN B)
665     { _data-=B._data; Fix_zero(); return *this; }
666     inline BigN operator*=(BigN B)
667     { _data*=B._data; Fix_zero(); return *this; }
668     inline BigN operator/=(BigN B)
669     { _data/=B._data; Fix_zero(); return *this; }
670     inline BigN operator%=(BigN B)
671     { _data%=B._data; Fix_zero(); return *this; }
672     inline BigN operator+=(int B) 
673     { _data+=B; Fix_zero(); return *this; }
674     inline BigN operator-=(int B) 
675     { _data-=B; Fix_zero(); return *this; }
676     inline BigN operator*=(int B) 
677     { _data*=B; Fix_zero(); return *this; }
678     inline BigN operator/=(int B) 
679     { _data/=B; Fix_zero(); return *this; }
680     inline BigN operator%=(int B) 
681     { _data%=B; Fix_zero(); return *this; }
682 
683     inline bool    operator < (BigN B)
684     {
685         if(_data.is_positive() && B._data.is_positive())
686             return _data.compare_abs(B._data)<0;
687         if(_data.is_negetive() && B._data.is_negetive())
688             return _data.compare_abs(B._data)>0;
689         if(_data.is_positive() && B._data.is_negetive()) return false;
690         return true;
691     }
692     inline bool    operator > (BigN B)
693     {
694         if(_data.is_positive() && B._data.is_positive())
695             return _data.compare_abs(B._data)>0;
696         if(_data.is_negetive() && B._data.is_negetive())
697             return _data.compare_abs(B._data)<0;
698         if(_data.is_positive() && B._data.is_negetive()) return true;
699         return false;
700     }
701     inline bool    operator == (BigN B)
702     {
703         if(_data.is_positive()!=B._data.is_positive()) return 0;
704         else return _data.compare_abs(B._data)==0;
705     }
706     inline bool    operator <= (BigN B) { return *this<B || *this==B; }
707     inline bool    operator >= (BigN B) { return *this>B || *this==B; }
708     inline bool    operator != (BigN B) { return !(*this==B); }
709 
710     inline bool    operator < (int B) { return *this<(BigN)B; }
711     inline bool    operator > (int B) { return *this>(BigN)B; }
712     inline bool    operator <= (int B) { return *this<=(BigN)B; }
713     inline bool    operator >= (int B) { return *this>=(BigN)B; }
714     inline bool    operator != (int B) { return *this!=(BigN)B; }
715     inline bool    operator == (int B) { return *this==(BigN)B; }
716 
717 
718     inline void    print() { _data.print(); }
719     inline void    printn() { _data.print(); printf("\n"); }
720 
721 
722     //These two functions both return std::string-type of the number.
723     //If it is the first time you try to get the string after an operation,
724     //you should use getstr(), for function str() will return the old
725     //string.
726     //Each time you call getstr(), the string will up-to-date.
727     //And you can use str(), after calling getstr() to save time.
728     inline std::string getstr(){ _data.print_to_str(_Str); return _Str; }
729     inline std::string str() { return _Str; }
730 
731     protected:
732     std::string _Str;
733     inline void    refresh_str() { _data.print_to_str(_Str); }
734 
735     private:
736     //this class contains real data and does the exact calculation
737     typedef _data_container_of_BigN _data_class;
738     _data_class _data;
739     public:
740     BigN() {}
741     BigN(const int x) { _data=x; }
742     BigN(const char* x) { _data=x; }
743 };
744 
745 BigN operator + (int A,BigN B) { return B+A; }
746 BigN operator * (int A,BigN B) { return B*A; }
747 
748 /***************************************************************************/
749 
750 char     a[1100000],b[1100000];
751 
752 int main()
753 {
754     scanf("%s%s",a,b);
755     BigN x=a,y=b,T;
756     printf("a+b="); (x+y).printn();
757     printf("a-b="); (x-y).printn();
758     printf("a*b="); (x*y).printn();
759     printf("a/b="); (x/y).printn();
760     printf("a%%b="); (x%y).printn();
761     printf("a*1000+b="); (T=x*1000+y).printn();
762     printf("2nd digit=%c\n",T.getstr().c_str()[2]);
763 
764     //These operation need definition of SAFE_CALC_MODE in line 33
765 
766     //T.modify(3,9);
767     //printf("after modify 3rd digit to 9="); T.printn();
768     //printf("3rd digit=");printf("%d\n",T[3]);
769     //printf("after unavailable operatorion="); T.modify(100,9);
770     //T.printn();
771     //printf("unavailable access="); printf("%d\n",T[100]);
772 
773     /*****************************************************/
774     //      Input:                                       //
775     //              123 45                               //
776     //      Output:                                      //
777     //              a+b=168                              //
778     //              a-b=78                               //
779     //              a*b=5535                             //
780     //              a/b=2                                //
781     //              a%b=33                               //
782     //              a*1000+b=123045                      //
783     //              2nd digit=3                          //
784     //              after modify 3rd digit to 9=123945   //
785     //              3rd digit=9                          //
786     //              after unavailable operatorion=123945 //
787     //              unavailable access=-1                //
788     /*****************************************************/
789     return 0;
790 }

 

posted @ 2017-12-12 23:34  Gster  阅读(1404)  评论(0编辑  收藏  举报