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