代码改变世界

BigNum模板

2014-03-07 15:07  gongti  阅读(415)  评论(0编辑  收藏  举报
  1 #include<iostream>
  2 #include<cstring>
  3 #include<iomanip>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 #define MAXN 9999
  8 #define MAXSIZE 10
  9 #define DLEN 4
 10 
 11 
 12 class BigNum
 13 {
 14 private:
 15     int a[500];    //可以控制大数的位数
 16     int len;       //大数长度
 17 public:
 18     BigNum(){ len = 1;memset(a,0,sizeof(a)); }   //构造函数
 19     BigNum(const int);       //将一个int类型的变量转化为大数
 20     BigNum(const char*);     //将一个字符串类型的变量转化为大数
 21     BigNum(const BigNum &);  //拷贝构造函数
 22     BigNum &operator=(const BigNum &);   //重载赋值运算符,大数之间进行赋值运算
 23 
 24     friend istream& operator>>(istream&,  BigNum&);   //重载输入运算符
 25     friend ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符
 26 
 27     BigNum operator+(const BigNum &) const;   //重载加法运算符,两个大数之间的相加运算
 28     BigNum operator-(const BigNum &) const;   //重载减法运算符,两个大数之间的相减运算
 29     BigNum operator*(const BigNum &) const;   //重载乘法运算符,两个大数之间的相乘运算
 30     BigNum operator/(const int   &) const;    //重载除法运算符,大数对一个整数进行相除运算
 31 
 32     BigNum operator^(const int  &) const;    //大数的n次方运算
 33     int    operator%(const int  &) const;    //大数对一个int类型的变量进行取模运算
 34     bool   operator>(const BigNum & T)const;   //大数和另一个大数的大小比较
 35     bool   operator>(const int & t)const;      //大数和一个int类型的变量的大小比较
 36 
 37     void print();       //输出大数
 38 };
 39 
 40 
 41 BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数
 42 {
 43     int c,d = b;
 44     len = 0;
 45     memset(a,0,sizeof(a));
 46     while(d > MAXN)
 47     {
 48         c = d - (d / (MAXN + 1)) * (MAXN + 1);
 49         d = d / (MAXN + 1);
 50         a[len++] = c;
 51     }
 52     a[len++] = d;
 53 }
 54 BigNum::BigNum(const char*s)     //将一个字符串类型的变量转化为大数
 55 {
 56     int t,k,index,l,i;
 57     memset(a,0,sizeof(a));
 58     l=strlen(s);
 59     len=l/DLEN;
 60     if(l%DLEN)
 61         len++;
 62     index=0;
 63     for(i=l-1;i>=0;i-=DLEN)
 64     {
 65         t=0;
 66         k=i-DLEN+1;
 67         if(k<0)
 68             k=0;
 69         for(int j=k;j<=i;j++)
 70             t=t*10+s[j]-'0';
 71         a[index++]=t;
 72     }
 73 }
 74 BigNum::BigNum(const BigNum & T) : len(T.len)  //拷贝构造函数
 75 {
 76     int i;
 77     memset(a,0,sizeof(a));
 78     for(i = 0 ; i < len ; i++)
 79         a[i] = T.a[i];
 80 }
 81 BigNum & BigNum::operator=(const BigNum & n)   //重载赋值运算符,大数之间进行赋值运算
 82 {
 83     int i;
 84     len = n.len;
 85     memset(a,0,sizeof(a));
 86     for(i = 0 ; i < len ; i++)
 87         a[i] = n.a[i];
 88     return *this;
 89 }
 90 istream& operator>>(istream & in,  BigNum & b)   //重载输入运算符
 91 {
 92     char ch[MAXSIZE*4];
 93     int i = -1;
 94     in>>ch;
 95     int l=strlen(ch);
 96     int count=0,sum=0;
 97     for(i=l-1;i>=0;)
 98     {
 99         sum = 0;
100         int t=1;
101         for(int j=0;j<4&&i>=0;j++,i--,t*=10)
102         {
103             sum+=(ch[i]-'0')*t;
104         }
105         b.a[count]=sum;
106         count++;
107     }
108     b.len =count++;
109     return in;
110 
111 }
112 ostream& operator<<(ostream& out,  BigNum& b)   //重载输出运算符
113 {
114     int i;
115     cout << b.a[b.len - 1];
116     for(i = b.len - 2 ; i >= 0 ; i--)
117     {
118         cout.width(DLEN);
119         cout.fill('0');
120         cout << b.a[i];
121     }
122     return out;
123 }
124 
125 BigNum BigNum::operator+(const BigNum & T) const   //两个大数之间的相加运算
126 {
127     BigNum t(*this);
128     int i,big;      //位数
129     big = T.len > len ? T.len : len;
130     for(i = 0 ; i < big ; i++)
131     {
132         t.a[i] +=T.a[i];
133         if(t.a[i] > MAXN)
134         {
135             t.a[i + 1]++;
136             t.a[i] -=MAXN+1;
137         }
138     }
139     if(t.a[big] != 0)
140         t.len = big + 1;
141     else
142         t.len = big;
143     return t;
144 }
145 BigNum BigNum::operator-(const BigNum & T) const   //两个大数之间的相减运算
146 {
147     int i,j,big;
148     bool flag;
149     BigNum t1,t2;
150     if(*this>T)
151     {
152         t1=*this;
153         t2=T;
154         flag=0;
155     }
156     else
157     {
158         t1=T;
159         t2=*this;
160         flag=1;
161     }
162     big=t1.len;
163     for(i = 0 ; i < big ; i++)
164     {
165         if(t1.a[i] < t2.a[i])
166         {
167             j = i + 1;
168             while(t1.a[j] == 0)
169                 j++;
170             t1.a[j--]--;
171             while(j > i)
172                 t1.a[j--] += MAXN;
173             t1.a[i] += MAXN + 1 - t2.a[i];
174         }
175         else
176             t1.a[i] -= t2.a[i];
177     }
178     t1.len = big;
179     while(t1.a[len - 1] == 0 && t1.len > 1)
180     {
181         t1.len--;
182         big--;
183     }
184     if(flag)
185         t1.a[big-1]=0-t1.a[big-1];
186     return t1;
187 }
188 
189 BigNum BigNum::operator*(const BigNum & T) const   //两个大数之间的相乘运算
190 {
191     BigNum ret;
192     int i,j,up;
193     int temp,temp1;
194     for(i = 0 ; i < len ; i++)
195     {
196         up = 0;
197         for(j = 0 ; j < T.len ; j++)
198         {
199             temp = a[i] * T.a[j] + ret.a[i + j] + up;
200             if(temp > MAXN)
201             {
202                 temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
203                 up = temp / (MAXN + 1);
204                 ret.a[i + j] = temp1;
205             }
206             else
207             {
208                 up = 0;
209                 ret.a[i + j] = temp;
210             }
211         }
212         if(up != 0)
213             ret.a[i + j] = up;
214     }
215     ret.len = i + j;
216     while(ret.a[ret.len - 1] == 0 && ret.len > 1)
217         ret.len--;
218     return ret;
219 }
220 BigNum BigNum::operator/(const int & b) const   //大数对一个整数进行相除运算
221 {
222     BigNum ret;
223     int i,down = 0;
224     for(i = len - 1 ; i >= 0 ; i--)
225     {
226         ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
227         down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
228     }
229     ret.len = len;
230     while(ret.a[ret.len - 1] == 0 && ret.len > 1)
231         ret.len--;
232     return ret;
233 }
234 int BigNum::operator %(const int & b) const    //大数对一个int类型的变量进行取模运算
235 {
236     int i,d=0;
237     for (i = len-1; i>=0; i--)
238     {
239         d = ((d * (MAXN+1))% b + a[i])% b;
240     }
241     return d;
242 }
243 BigNum BigNum::operator^(const int & n) const    //大数的n次方运算
244 {
245     BigNum t,ret(1);
246     int i;
247     if(n<0)
248         exit(-1);
249     if(n==0)
250         return 1;
251     if(n==1)
252         return *this;
253     int m=n;
254     while(m>1)
255     {
256         t=*this;
257         for( i=1;i<<1<=m;i<<=1)
258         {
259             t=t*t;
260         }
261         m-=i;
262         ret=ret*t;
263         if(m==1)
264             ret=ret*(*this);
265     }
266     return ret;
267 }
268 bool BigNum::operator>(const BigNum & T) const   //大数和另一个大数的大小比较
269 {
270     int ln;
271     if(len > T.len)
272         return true;
273     else if(len == T.len)
274     {
275         ln = len - 1;
276         while(a[ln] == T.a[ln] && ln >= 0)
277             ln--;
278         if(ln >= 0 && a[ln] > T.a[ln])
279             return true;
280         else
281             return false;
282     }
283     else
284         return false;
285 }
286 bool BigNum::operator >(const int & t) const    //大数和一个int类型的变量的大小比较
287 {
288     BigNum b(t);
289     return *this>b;
290 }
291 
292 void BigNum::print()    //输出大数
293 {
294     int i;
295     cout << a[len - 1];
296     for(i = len - 2 ; i >= 0 ; i--)
297     {
298         cout.width(DLEN);
299         cout.fill('0');
300         cout << a[i];
301     }
302     cout << endl;
303 }