码迷,mamicode.com
首页 > 其他好文 > 详细

高精度模板

时间:2015-06-30 14:22:13      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:

高精度模板,留个备份:

  1 #include <cstdio>
  2 #include <cstring>
  3 
  4 struct BigNumber
  5 {
  6     static const long long BASE = 1000000000;
  7     static const int BASEDIGS = 9;
  8     
  9     int ndigs;
 10     long long *digs;
 11     
 12     void init(int n, const long long *d)
 13     {
 14         while (n > 0 && d[n - 1] == 0)
 15             --n;
 16         ndigs = n;
 17         digs = new long long[n];
 18         for (int i = 0; i < n; ++i)
 19             digs[i] = d[i];
 20     }
 21     
 22     BigNumber(int n, const long long *d)
 23     {
 24         init(n, d);
 25     }
 26     
 27     BigNumber operator <<(int sh) const
 28     {
 29         int n = sh + ndigs;
 30         long long d[n];
 31         for (int i = 0; i < sh; ++i)
 32             d[i] = 0;
 33         for (int i = 0; i < ndigs; ++i)
 34             d[i + sh] = digs[i];
 35         return BigNumber(n, d);
 36     }
 37     
 38     BigNumber(long long x = 0)
 39     {
 40         long long d[2];
 41         d[0] = x % BASE;
 42         d[1] = x / BASE;
 43         init(2, d);
 44     }
 45     
 46     BigNumber(const BigNumber&a)
 47     {
 48         init(a.ndigs, a.digs);
 49     }
 50     
 51     BigNumber(const char *s)
 52     {
 53         int n = strlen(s), nd = n / BASEDIGS + 1;
 54         long long d[nd];
 55         for (int i = 0; i < nd; i++)
 56         {
 57             d[i] = 0;
 58             for (int j = BASEDIGS - 1; j >= 0; j--)
 59             {
 60                 long long poz = i * BASEDIGS + j;
 61                 if (poz < n) d[i] = 10 * d[i] + s[n - 1 - poz] - 0;
 62             }
 63         }
 64         init(nd, d);
 65     }
 66     
 67     ~BigNumber()
 68     {
 69         delete[] digs;
 70     }
 71     
 72     BigNumber &operator =(const BigNumber &a)
 73     {
 74         delete[] digs;
 75         init(a.ndigs, a.digs);
 76         return *this;
 77     }
 78 
 79     BigNumber operator +(const BigNumber &a) const
 80     {
 81         int n = (ndigs > a.ndigs ? ndigs : a.ndigs) + 1;
 82         long long d[n];
 83         for (int i = 0; i < n; i++)
 84             d[i] = 0;
 85         for (int i = 0; i < n; i++)
 86         {
 87             if (i < ndigs) d[i] += digs[i];
 88             if (i < a.ndigs) d[i] += a.digs[i];
 89             if (d[i] >= BASE)
 90             {
 91                 d[i] -= BASE;
 92                 ++d[i + 1];
 93             }
 94         }
 95         return BigNumber(n, d);
 96     }
 97     
 98     BigNumber &operator +=(const BigNumber &a)
 99     {
100         return *this = *this + a;
101     }
102 
103     BigNumber operator -(const BigNumber &a) const
104     {
105         long long d[ndigs];
106         for (int i = 0; i < ndigs; i++)
107             d[i] = digs[i];
108         for (int i = 0; i < ndigs; i++)
109         {
110             if (i < a.ndigs) d[i] -= a.digs[i];
111             if (d[i] < 0)
112             {
113                 d[i] += BASE;
114                 --d[i + 1];
115             }
116         }
117         return BigNumber(ndigs, d);
118     }
119     
120     BigNumber &operator -=(const BigNumber &a)
121     {
122         return *this = *this - a;
123     }
124     
125     BigNumber operator *(const BigNumber &a) const
126     {
127         int n = ndigs + a.ndigs;
128         long long d[n];
129         for (int i = 0; i < n; i++)
130             d[i] = 0;
131         for (int i = 0; i < ndigs; i++)
132         {
133             long long p = 0;
134             for (int j = 0; j < a.ndigs; j++)
135             {
136                 long long v = (long long) (digs[i]) * a.digs[j];
137                 long long v1 = v / BASE, v0 = v % BASE;
138                 d[i + j] += v0 + p;
139                 p = v1 + d[i + j] / BASE;
140                 d[i + j] %= BASE;
141             }
142             for(int j = i + a.ndigs; p > 0; ++j)
143             {
144                 d[j] += p;
145                 p = d[j] / BASE;
146                 d[j] %= BASE;
147             }
148         }
149         return BigNumber(n, d);
150     }
151     
152     BigNumber &operator *=(const BigNumber &a)
153     {
154         return *this = *this * a;
155     }
156     
157     BigNumber operator /(const BigNumber &a) const
158     {
159         int n = (ndigs - a.ndigs + 1 > 0 ? ndigs - a.ndigs + 1 : 0);
160         long long d[n];
161         BigNumber prod;
162         for(int i = n - 1; i >= 0; i--)
163         {
164             long long l = 0, r = BASE - 1;
165             while(l < r)
166             {
167                 long long m = (l + r + 1) / 2;
168                 if (*this < prod + (a * m << i))
169                     r = m - 1;
170                 else l = m;
171             }
172             prod += a * l << i;
173             d[i] = l;
174         }
175         return BigNumber(n, d);
176     }
177     
178     BigNumber &operator /=(const BigNumber &a)
179     {
180         return *this = *this / a;
181     }
182     
183     BigNumber operator %(const BigNumber &a) const 
184     {
185         return *this - *this / a * a;
186     }
187     
188     BigNumber &operator%=(const BigNumber&a) {
189         return *this = *this % a;
190     }
191     
192     BigNumber sqrt() const
193     {
194         int n = (ndigs + 1) / 2;
195         long long d[n];
196         for (int i = 0; i < n; i++)
197             d[i] = 0;
198         BigNumber sq;
199         for (int i = n - 1; i >= 0; i--)
200         {
201             BigNumber a(n, d);
202             long long l = 0, r = BASE - 1;
203             while (l < r) {
204                 long long m = (l + r + 1) / 2;
205                 if (*this < sq + (a * 2 * m << i) + (BigNumber(m) * m << 2 * i))
206                     r = m - 1;
207                 else l = m;
208             }
209             sq += (a * 2 * l << i) + (BigNumber(l) * l << 2 * i);
210             d[i] = l;
211         }
212         return BigNumber(n, d);
213     }
214 
215     BigNumber operator *(long long x) const
216     {
217         int n = ndigs + 1;
218         long long d[n];
219         long long a = 0;
220         for (int i = 0; i < ndigs; i++)
221         {
222             a += digs[i] * x;
223             d[i] = a % BASE;
224             a /= BASE;
225         }
226         d[ndigs] = a;
227         return BigNumber(n, d);
228     }
229     
230     BigNumber &operator *=(long long x)
231     {
232         return *this = *this * x;
233     }
234 
235     BigNumber operator /(long long x) const
236     {
237         long long d[ndigs];
238         long long a = 0;
239         for (int i = ndigs - 1; i >= 0; i--)
240         {
241             a = BASE * a + digs[i];
242             d[i] = a / x;
243             a %= x;
244         }
245         return BigNumber(ndigs, d);
246     }
247     
248     BigNumber &operator /=(long long x)
249     {
250         return *this = *this / x;
251     }
252     
253     long long operator %(long long x) const
254     {
255         long long a = 0;
256         for (int i = ndigs - 1; i >= 0; i--)
257         {
258             a = BASE * a + digs[i];
259             a %= x;
260         }
261         return a;
262     }
263     
264     bool operator <(const BigNumber &a) const
265     {
266         if (ndigs < a.ndigs) return true;
267         if (ndigs > a.ndigs) return false;
268         for(int i = ndigs - 1; i >= 0; i--)
269         {
270             if (digs[i] < a.digs[i]) return true;
271             if (digs[i] > a.digs[i]) return false;
272         }
273         return false;
274     }
275     
276     bool operator ==(const BigNumber &a) const
277     {
278         if (ndigs != a.ndigs) return false;
279         for (int i = 0; i < ndigs; i++)
280         {
281             if (digs[i] != a.digs[i])
282                 return false;
283         }
284         return true;
285     }
286     
287     bool operator >(const BigNumber &a) const
288     {
289         return a < *this;
290     }
291     
292     bool operator <=(const BigNumber &a) const
293     {
294         return !(a < *this);
295     }
296     
297     bool operator >=(const BigNumber &a) const
298     {
299         return !(*this < a);
300     }
301     
302     bool operator !=(const BigNumber &a) const
303     {
304         return !(*this == a);
305     }
306 
307     void write() const
308     {
309         if (ndigs == 0) printf("0");
310         else
311         {
312             printf("%lld", digs[ndigs - 1]);
313             for (int i = ndigs - 2; i >= 0; i--)
314                 printf("%0*lld", BASEDIGS, digs[i]);
315         }
316     }
317     
318     void write(char *buf) const
319     {
320         if(ndigs == 0) sprintf(buf, "0");
321         else
322         {
323             long long pos = 0;
324             pos += sprintf(buf, "%lld", digs[ndigs - 1]);
325             for (int i = ndigs - 2; i >= 0; i--)
326                 pos += sprintf(buf + pos, "%0*lld", BASEDIGS, digs[i]);
327         }
328     }
329 };

 

高精度模板

标签:

原文地址:http://www.cnblogs.com/lightning34/p/4610087.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!