Decided against the start-of-file comment.
[bigint/bigint.git] / BigInteger.cc
1 #include "BigInteger.hh"
2
3 // MANAGEMENT
4
5 // Assignment operator
6 void BigInteger::operator =(const BigInteger &x) {
7         // Calls like a = a have no effect
8         if (this == &x)
9                 return;
10         // Copy sign
11         sign = x.sign;
12         // Copy the rest
13         BigUnsigned::operator =(x);
14 }
15
16 // Constructor from an array of blocks and a sign
17 BigInteger::BigInteger(const Blk *b, Index l, Sign s) : BigUnsigned(b, l) {
18         switch (s) {
19                 case zero:
20                 case positive:
21                 case negative:
22                 sign = (len == 0) ? zero : s;
23                 break;
24                 default:
25                 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
26         }
27 }
28
29 // Constructor from a BigUnsigned and a sign
30 BigInteger::BigInteger(const BigUnsigned &x, Sign s) : BigUnsigned(x) {
31         switch (s) {
32                 case zero:
33                 case positive:
34                 case negative:
35                 sign = (len == 0) ? zero : s;
36                 break;
37                 default:
38                 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
39         }
40 }
41
42 /*
43  * The steps for construction of a BigInteger
44  * from an integral value x are as follows:
45  * 1. If x is zero, create an empty BigInteger and stop.
46  * 2. Allocate a one-block number array.
47  * 3. If x is positive (or of an unsigned type), set the
48  *    sign of the BigInteger to positive.
49  * 4. If x is of a signed type and is negative, set the
50  *    sign of the BigInteger to negative.
51  * 5. If x is of a signed type, convert x (or -x if x < 0)
52  *    to the unsigned type of the same length.
53  * 6. Expand x (or the result of step 5) to a Blk,
54  *    and store it in the number array.
55  *
56  * See remarks in `BigUnsigned.cc' and `NumberlikeArray.hh'
57  * about new handling of zero-length arrays.
58  */
59
60 BigInteger::BigInteger(unsigned long x) {
61         if (x == 0)
62                 sign = zero; // NumberlikeArray did the rest
63         else {
64                 cap = 1;
65                 blk = new Blk[1];
66                 sign = positive;
67                 len = 1;
68                 blk[0] = Blk(x);
69         }
70 }
71
72 BigInteger::BigInteger(long x) {
73         if (x > 0) {
74                 cap = 1;
75                 blk = new Blk[1];
76                 sign = positive;
77                 len = 1;
78                 blk[0] = Blk(x);
79         } else if (x < 0) {
80                 cap = 1;
81                 blk = new Blk[1];
82                 sign = negative;
83                 len = 1;
84                 blk[0] = Blk(-x);
85         } else
86         sign = zero;
87 }
88
89 BigInteger::BigInteger(unsigned int x) {
90         if (x == 0)
91                 sign = zero;
92         else {
93                 cap = 1;
94                 blk = new Blk[1];
95                 sign = positive;
96                 len = 1;
97                 blk[0] = Blk(x);
98         }
99 }
100
101 BigInteger::BigInteger(int x) {
102         if (x > 0) {
103                 cap = 1;
104                 blk = new Blk[1];
105                 sign = positive;
106                 len = 1;
107                 blk[0] = Blk(x);
108         } else if (x < 0) {
109                 cap = 1;
110                 blk = new Blk[1];
111                 sign = negative;
112                 len = 1;
113                 blk[0] = Blk(-x);
114         } else
115         sign = zero;
116 }
117
118 BigInteger::BigInteger(unsigned short x) {
119         if (x == 0)
120                 sign = zero;
121         else {
122                 cap = 1;
123                 blk = new Blk[1];
124                 sign = positive;
125                 len = 1;
126                 blk[0] = Blk(x);
127         }
128 }
129
130 BigInteger::BigInteger(short x) {
131         if (x > 0) {
132                 cap = 1;
133                 blk = new Blk[1];
134                 sign = positive;
135                 len = 1;
136                 blk[0] = Blk(x);
137         } else if (x < 0) {
138                 cap = 1;
139                 blk = new Blk[1];
140                 sign = negative;
141                 len = 1;
142                 blk[0] = Blk(-x);
143         } else
144         sign = zero;
145 }
146
147 // CONVERTERS
148 /*
149  * The steps for conversion of a BigInteger to an
150  * integral type are as follows:
151  * 1. If the BigInteger is zero, return zero.
152  * 2. If the BigInteger is positive:
153  *    3. If it is more than one block long or its lowest
154  *       block has bits set out of the range of the target
155  *       type, throw an exception.
156  *    4. Otherwise, convert the lowest block to the
157  *       target type and return it.
158  * 5. If the BigInteger is negative:
159  *    6. If the target type is unsigned, throw an exception.
160  *    7. If it is more than one block long or its lowest
161  *       block has bits set out of the range of the target
162  *       type, throw an exception.
163  *    8. Otherwise, convert the lowest block to the
164  *       target type, negate it, and return it.
165  */
166
167 namespace {
168         // These masks are used to test whether a Blk has bits
169         // set out of the range of a smaller integral type.  Note
170         // that this range is not considered to include the sign bit.
171         const BigUnsigned::Blk  lMask = ~0 >> 1;
172         const BigUnsigned::Blk uiMask = (unsigned int)(~0);
173         const BigUnsigned::Blk  iMask = uiMask >> 1;
174         const BigUnsigned::Blk usMask = (unsigned short)(~0);
175         const BigUnsigned::Blk  sMask = usMask >> 1;
176 }
177
178 BigInteger::operator unsigned long() const {
179         switch (sign) {
180                 case zero:
181                 return 0;
182                 case positive:
183                 if (len == 1)
184                         return blk[0];
185                 else
186                         throw "BigInteger operator unsigned long() const: Value is too big for an unsigned long";
187                 case negative:
188                 throw "BigInteger operator unsigned long() const: Cannot convert a negative integer to an unsigned type";
189                 default:
190                 throw "BigInteger: Internal error";
191         }
192 }
193
194 BigInteger::operator long() const {
195         switch (sign) {
196                 case zero:
197                 return 0;
198                 case positive:
199                 if (len == 1 && (blk[0] & ~lMask) == 0)
200                         return long(blk[0]);
201                 else
202                         throw "BigInteger operator long() const: Value is too big for a long";
203                 case negative:
204                 if (len == 1 && (blk[0] & ~lMask) == 0)
205                         return -long(blk[0]);
206                 else
207                         throw "BigInteger operator long() const: Value is too big for a long";
208                 default:
209                 throw "BigInteger: Internal error";
210         }
211 }
212
213 BigInteger::operator unsigned int() const {
214         switch (sign) {
215                 case zero:
216                 return 0;
217                 case positive:
218                 if (len == 1 && (blk[0] & ~uiMask) == 0)
219                         return (unsigned int)(blk[0]);
220                 else
221                         throw "BigInteger operator unsigned int() const: Value is too big for an unsigned int";
222                 case negative:
223                 throw "BigInteger operator unsigned int() const: Cannot convert a negative integer to an unsigned type";
224                 default:
225                 throw "BigInteger: Internal error";
226         }
227 }
228
229 BigInteger::operator int() const {
230         switch (sign) {
231                 case zero:
232                 return 0;
233                 case positive:
234                 if (len == 1 && (blk[0] & ~iMask) == 0)
235                         return int(blk[0]);
236                 else
237                         throw "BigInteger operator int() const: Value is too big for an int";
238                 case negative:
239                 if (len == 1 && (blk[0] & ~iMask) == 0)
240                         return -int(blk[0]);
241                 else
242                         throw "BigInteger operator int() const: Value is too big for an int";
243                 default:
244                 throw "BigInteger: Internal error";
245         }
246 }
247
248 BigInteger::operator unsigned short() const {
249         switch (sign) {
250                 case zero:
251                 return 0;
252                 case positive:
253                 if (len == 1 && (blk[0] & ~usMask) == 0)
254                         return (unsigned short)(blk[0]);
255                 else
256                         throw "BigInteger operator unsigned short() const: Value is too big for an unsigned short";
257                 case negative:
258                 throw "BigInteger operator unsigned short() const: Cannot convert a negative integer to an unsigned type";
259                 default:
260                 throw "BigInteger: Internal error";
261         }
262 }
263
264 BigInteger::operator short() const {
265         switch (sign) {
266                 case zero:
267                 return 0;
268                 case positive:
269                 if (len == 1 && (blk[0] & ~sMask) == 0)
270                         return short(blk[0]);
271                 else
272                         throw "BigInteger operator short() const: Value is too big for a short";
273                 case negative:
274                 if (len == 1 && (blk[0] & ~sMask) == 0)
275                         return -short(blk[0]);
276                 else
277                         throw "BigInteger operator short() const: Value is too big for a short";
278                 default:
279                 throw "BigInteger: Internal error";
280         }
281 }
282
283 // COMPARISON
284 BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
285         // A greater sign implies a greater number
286         if (sign < x.sign)
287                 return less;
288         else if (sign > x.sign)
289                 return greater;
290         else switch (sign) {
291                 // If the signs are the same...
292                 case zero:
293                 return equal; // Two zeros are equal
294                 case positive:
295                 // Compare the magnitudes
296                 return BigUnsigned::compareTo(x);
297                 case negative:
298                 // Compare the magnitudes, but return the opposite result
299                 return CmpRes(-BigUnsigned::compareTo(x));
300                 default:
301                 throw "BigInteger: Internal error";
302         }
303 }
304
305 // PUT-HERE OPERATIONS
306 // These do some messing around to determine the sign of the result,
307 // then call one of BigUnsigned's put-heres.
308
309 // See remarks about aliased calls in BigUnsigned.cc .
310 #define DTRT_ALIASED(cond, op) \
311         if (cond) { \
312                 BigInteger tmpThis; \
313                 tmpThis.op; \
314                 *this = tmpThis; \
315                 return; \
316         }
317
318 // Addition
319 void BigInteger::add(const BigInteger &a, const BigInteger &b) {
320         DTRT_ALIASED(this == &a || this == &b, add(a, b));
321         // If one argument is zero, copy the other.
322         if (a.sign == zero)
323                 operator =(b);
324         else if (b.sign == zero)
325                 operator =(a);
326         // If the arguments have the same sign, take the
327         // common sign and add their magnitudes.
328         else if (a.sign == b.sign) {
329                 sign = a.sign;
330                 BigUnsigned::add(a, b);
331         } else {
332                 // Otherwise, their magnitudes must be compared.
333                 switch (a.BigUnsigned::compareTo(b)) {
334                         // If their magnitudes are the same, copy zero.
335                         case equal:
336                         len = 0;
337                         sign = zero;
338                         break;
339                         // Otherwise, take the sign of the greater, and subtract
340                         // the lesser magnitude from the greater magnitude.
341                         case greater:
342                         sign = a.sign;
343                         BigUnsigned::subtract(a, b);
344                         break;
345                         case less:
346                         sign = b.sign;
347                         BigUnsigned::subtract(b, a);
348                         break;
349                 }
350         }
351 }
352
353 // Subtraction
354 void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
355         // Notice that this routine is identical to BigInteger::add,
356         // if one replaces b.sign by its opposite.
357         DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
358         // If a is zero, copy b and flip its sign.  If b is zero, copy a.
359         if (a.sign == zero) {
360                 BigUnsigned::operator =(b);
361                 // Take the negative of _b_'s, sign, not ours.
362                 // Bug pointed out by Sam Larkin on 2005.03.30.
363                 sign = Sign(-b.sign);
364         } else if (b.sign == zero)
365                 operator =(a);
366         // If their signs differ, take a.sign and add the magnitudes.
367         else if (a.sign != b.sign) {
368                 sign = a.sign;
369                 BigUnsigned::add(a, b);
370         } else {
371                 // Otherwise, their magnitudes must be compared.
372                 switch (a.BigUnsigned::compareTo(b)) {
373                         // If their magnitudes are the same, copy zero.
374                         case equal:
375                         len = 0;
376                         sign = zero;
377                         break;
378                         // If a's magnitude is greater, take a.sign and
379                         // subtract a from b.
380                         case greater:
381                         sign = a.sign;
382                         BigUnsigned::subtract(a, b);
383                         break;
384                         // If b's magnitude is greater, take the opposite
385                         // of b.sign and subtract b from a.
386                         case less:
387                         sign = Sign(-b.sign);
388                         BigUnsigned::subtract(b, a);
389                         break;
390                 }
391         }
392 }
393
394 // Multiplication
395 void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
396         DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
397         // If one object is zero, copy zero and return.
398         if (a.sign == zero || b.sign == zero) {
399                 sign = zero;
400                 len = 0;
401                 return;
402         }
403         // If the signs of the arguments are the same, the result
404         // is positive, otherwise it is negative.
405         sign = (a.sign == b.sign) ? positive : negative;
406         // Multiply the magnitudes.
407         BigUnsigned::multiply(a, b);
408 }
409
410 /*
411  * DIVISION WITH REMAINDER
412  * Please read the comments before the definition of
413  * `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
414  * information you should know before reading this function.
415  *
416  * Following Knuth, I decree that x / y is to be
417  * 0 if y==0 and floor(real-number x / y) if y!=0.
418  * Then x % y shall be x - y*(integer x / y).
419  *
420  * Note that x = y * (x / y) + (x % y) always holds.
421  * In addition, (x % y) is from 0 to y - 1 if y > 0,
422  * and from -(|y| - 1) to 0 if y < 0.  (x % y) = x if y = 0.
423  *
424  * Examples: (q = a / b, r = a % b)
425  *      a       b       q       r
426  *      ===     ===     ===     ===
427  *      4       3       1       1
428  *      -4      3       -2      2
429  *      4       -3      -2      -2
430  *      -4      -3      1       -1
431  */
432 void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
433         // Defend against aliased calls;
434         // same idea as in BigUnsigned::divideWithRemainder .
435         if (this == &q)
436                 throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
437         if (this == &b || &q == &b) {
438                 BigInteger tmpB(b);
439                 divideWithRemainder(tmpB, q);
440                 return;
441         }
442
443         // Division by zero gives quotient 0 and remainder *this
444         if (b.sign == zero) {
445                 q.len = 0;
446                 q.sign = zero;
447                 return;
448         }
449         // 0 / b gives quotient 0 and remainder 0
450         if (sign == zero) {
451                 q.len = 0;
452                 q.sign = zero;
453                 return;
454         }
455
456         // Here *this != 0, b != 0.
457
458         // Do the operands have the same sign?
459         if (sign == b.sign) {
460                 // Yes: easy case.  Quotient is zero or positive.
461                 q.sign = positive;
462         } else {
463                 // No: harder case.  Quotient is negative.
464                 q.sign = negative;
465                 // Decrease the magnitude of the dividend by one.
466                 BigUnsigned::operator --();
467                 /*
468                  * We tinker with the dividend before and with the
469                  * quotient and remainder after so that the result
470                  * comes out right.  To see why it works, consider the following
471                  * list of examples, where A is the magnitude-decreased
472                  * a, Q and R are the results of BigUnsigned division
473                  * with remainder on A and |b|, and q and r are the
474                  * final results we want:
475                  *
476                  *      a       A       b       Q       R       q       r
477                  *      -3      -2      3       0       2       -1      0
478                  *      -4      -3      3       1       0       -2      2
479                  *      -5      -4      3       1       1       -2      1
480                  *      -6      -5      3       1       2       -2      0
481                  *
482                  * It appears that we need a total of 3 corrections:
483                  * Decrease the magnitude of a to get A.  Increase the
484                  * magnitude of Q to get q (and make it negative).
485                  * Find r = (b - 1) - R and give it the desired sign.
486                  */
487         }
488
489         // Divide the magnitudes.
490         BigUnsigned::divideWithRemainder(b, q);
491
492         if (sign != b.sign) {
493                 // More for the harder case (as described):
494                 // Increase the magnitude of the quotient by one.
495                 q.BigUnsigned::operator ++();
496                 // Modify the remainder.
497                 BigUnsigned temp(*this);
498                 BigUnsigned::subtract(b, temp);
499                 BigUnsigned::operator --();
500         }
501
502         // Sign of the remainder is always the sign of the divisor b.
503         sign = b.sign;
504
505         // Set signs to zero as necessary.  (Thanks David Allen!)
506         if (len == 0)
507                 sign = zero;
508         if (q.len == 0)
509                 q.sign = zero;
510
511         // WHEW!!!
512 }
513
514 // Negation
515 void BigInteger::negate(const BigInteger &a) {
516         DTRT_ALIASED(this == &a, negate(a));
517         // Copy a's magnitude
518         BigUnsigned::operator =(a);
519         // Copy the opposite of a.sign
520         sign = Sign(-a.sign);
521 }
522
523 // INCREMENT/DECREMENT OPERATORS
524
525 // Prefix increment
526 void BigInteger::operator ++() {
527         switch (sign) {
528                 case zero:
529                 allocate(1);
530                 sign = positive;
531                 len = 1;
532                 blk[0] = 1;
533                 break;
534                 case positive:
535                 BigUnsigned::operator ++();
536                 break;
537                 case negative:
538                 BigUnsigned::operator --();
539                 if (len == 0)
540                         sign = zero;
541                 break;
542         }
543 }
544
545 // Postfix increment: same as prefix
546 void BigInteger::operator ++(int) {
547         operator ++();
548 }
549
550 // Prefix decrement
551 void BigInteger::operator --() {
552         switch (sign) {
553                 case zero:
554                 allocate(1);
555                 sign = negative;
556                 len = 1;
557                 blk[0] = 1;
558                 break;
559                 case negative:
560                 BigUnsigned::operator ++();
561                 break;
562                 case positive:
563                 BigUnsigned::operator --();
564                 if (len == 0)
565                         sign = zero;
566                 break;
567         }
568 }
569
570 // Postfix decrement: same as prefix
571 void BigInteger::operator --(int) {
572         operator --();
573 }
574