2 * Matt McCutchen's Big Integer Library
3 * http://mysite.verizon.net/mccutchen/bigint/
6 #include "BigUnsigned.h"
10 // This routine is called to ensure the number array is at least a
11 // certain size before the result of an operation is written over it.
12 void BigUnsigned::allocate(BlkNum c) {
13 // If the requested capacity is more than the current capacity...
15 // Delete the old number array
17 // Allocate the new array
23 // This routine is called to ensure the number array is at least a
24 // certain size without losing its contents.
25 void BigUnsigned::allocateAndCopy(BlkNum c) {
26 // If the requested capacity is more than the current capacity...
29 // Allocate the new number array
36 for (i = 0, blkI = blk, oldBlkI = oldBlk; i < len; i++, blkI++, oldBlkI++)
38 // Delete the old array
44 BigUnsigned::BigUnsigned(const BigUnsigned &x) : len(x.len) {
45 // Create number array
52 for (i = 0, blkI = blk, xBlkI = x.blk; i < len; i++, blkI++, xBlkI++)
56 // Assignment operator
57 void BigUnsigned::operator=(const BigUnsigned &x) {
58 // Calls like a = a have no effect
63 // Expand number array if necessary
69 for (i = 0, blkI = blk, xBlkI = x.blk; i < len; i++, blkI++, xBlkI++)
73 // Constructor from an array of blocks
74 BigUnsigned::BigUnsigned(const Blk *b, BlkNum l) : cap(l), len(l) {
75 // Create number array
81 for (i = 0, blkI = blk, bI = b; i < len; i++, blkI++, bI++)
87 * The steps for construction of a BigUnsigned
88 * from an integral value x are as follows:
89 * 1. If x is zero, create an empty BigUnsigned and stop.
90 * 2. If x is negative, throw an exception.
91 * 3. Allocate a one-block number array.
92 * 4. If x is of a signed type, convert x to the unsigned
93 * type of the same length.
94 * 5. Expand x to a Blk, and store it in the number array.
97 BigUnsigned::BigUnsigned(unsigned long x) {
110 BigUnsigned::BigUnsigned(long x) {
121 throw "BigUnsigned::BigUnsigned(long): Cannot construct a BigUnsigned from a negative number";
124 BigUnsigned::BigUnsigned(unsigned int x) {
137 BigUnsigned::BigUnsigned(int x) {
148 throw "BigUnsigned::BigUnsigned(int): Cannot construct a BigUnsigned from a negative number";
151 BigUnsigned::BigUnsigned(unsigned short x) {
164 BigUnsigned::BigUnsigned(short x) {
175 throw "BigUnsigned::BigUnsigned(short): Cannot construct a BigUnsigned from a negative number";
180 * The steps for conversion of a BigUnsigned to an
181 * integral type are as follows:
182 * 1. If the BigUnsigned is zero, return zero.
183 * 2. If it is more than one block long or its lowest
184 * block has bits set out of the range of the target
185 * type, throw an exception.
186 * 3. Otherwise, convert the lowest block to the
187 * target type and return it.
191 // These masks are used to test whether a Blk has bits
192 // set out of the range of a smaller integral type. Note
193 // that this range is not considered to include the sign bit.
194 const BigUnsigned::Blk lMask = ~0 >> 1;
195 const BigUnsigned::Blk uiMask = (unsigned int)(~0);
196 const BigUnsigned::Blk iMask = uiMask >> 1;
197 const BigUnsigned::Blk usMask = (unsigned short)(~0);
198 const BigUnsigned::Blk sMask = usMask >> 1;
201 BigUnsigned::operator unsigned long() const {
205 return (unsigned long) *blk;
207 throw "BigUnsigned::operator unsigned long: Value is too big for an unsigned long";
210 BigUnsigned::operator long() const {
213 else if (len == 1 && (*blk & lMask) == *blk)
216 throw "BigUnsigned::operator long: Value is too big for a long";
219 BigUnsigned::operator unsigned int() const {
222 else if (len == 1 && (*blk & uiMask) == *blk)
223 return (unsigned int) *blk;
225 throw "BigUnsigned::operator unsigned int: Value is too big for an unsigned int";
228 BigUnsigned::operator int() const {
231 else if (len == 1 && (*blk & iMask) == *blk)
234 throw "BigUnsigned::operator int: Value is too big for an int";
237 BigUnsigned::operator unsigned short() const {
240 else if (len == 1 && (*blk & usMask) == *blk)
241 return (unsigned short) *blk;
243 throw "BigUnsigned::operator unsigned short: Value is too big for an unsigned short";
246 BigUnsigned::operator short() const {
249 else if (len == 1 && (*blk & sMask) == *blk)
252 throw "BigUnsigned::operator short: Value is too big for a short";
256 BigUnsigned::CmpRes BigUnsigned::compareTo(const BigUnsigned &x) const {
257 // A bigger length implies a bigger number.
260 else if (len > x.len)
263 // Compare blocks one by one from left to right.
265 const Blk *blkI = blk + len;
266 const Blk *xBlkI = x.blk + len;
273 else if (*blkI > *xBlkI)
278 // If no blocks differed, the numbers are equal.
283 // PUT-HERE OPERATIONS
286 void BigUnsigned::add(const BigUnsigned &a, const BigUnsigned &b) {
287 // Block unsafe calls
288 if (this == &a || this == &b)
289 throw "BigUnsigned::add: One of the arguments is the invoked object";
290 // If one argument is zero, copy the other.
294 } else if (b.len == 0) {
298 // Carries in and out of an addition stage
299 bool carryIn, carryOut;
302 // a2 points to the longer input, b2 points to the shorter
303 const BigUnsigned *a2, *b2;
304 if (a.len >= b.len) {
311 // These point directly to the position of interest in the
312 // corresponding block arrays, for faster access.
314 const Blk *a2BlkI, *b2BlkI;
315 // Set prelimiary length and make room in this BigUnsigned
318 // For each block index that is present in both inputs...
319 for (i = 0, blkI = blk, a2BlkI = a2->blk, b2BlkI = b2->blk,
320 carryIn = false; i < b2->len; i++, blkI++, a2BlkI++, b2BlkI++) {
322 temp = *a2BlkI + *b2BlkI;
323 // If a rollover occurred, the result is less than either input.
324 // This test is used many times in the BigUnsigned code.
325 carryOut = (temp < *a2BlkI);
326 // If a carry was input, handle it
329 carryOut |= (temp == 0);
331 *blkI = temp; // Save the addition result
332 carryIn = carryOut; // Pass the carry along
334 // If there is a carry left over, increase blocks until
335 // one does not roll over.
336 for (; i < a2->len && carryIn; i++, blkI++, a2BlkI++) {
338 carryIn = (temp == 0);
341 // If the carry was resolved but the larger number
342 // still has blocks, copy them over.
343 for (; i < a2->len; i++, blkI++, a2BlkI++)
345 // Set the extra block if there's still a carry, decrease length otherwise
353 void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) {
354 // Block unsafe calls
355 if (this == &a || this == &b)
356 throw "BigUnsigned::subtract: One of the arguments is the invoked object";
357 // If b is zero, copy a. If a is shorter than b, the result is negative.
361 } else if (a.len < b.len)
362 throw "BigUnsigned::subtract: Negative result in unsigned calculation";
363 bool borrowIn, borrowOut;
366 // These point directly to the position of interest in the
367 // corresponding block arrays, for faster access.
369 const Blk *aBlkI, *bBlkI;
370 // Set preliminary length and make room
373 // For each block index that is present in both inputs...
374 for (i = 0, blkI = blk, aBlkI = a.blk, bBlkI = b.blk,
375 borrowIn = false; i < b.len; i++, blkI++, aBlkI++, bBlkI++) {
376 temp = *aBlkI - *bBlkI;
377 // If a reverse rollover occurred, the result is greater than the block from a.
378 borrowOut = (temp > *aBlkI);
379 // Handle an incoming borrow
381 borrowOut |= (temp == 0);
384 *blkI = temp; // Save the subtraction result
385 borrowIn = borrowOut; // Pass the borrow along
387 // If there is a borrow left over, decrease blocks until
388 // one does not reverse rollover.
389 for (; i < a.len && borrowIn; i++, blkI++, aBlkI++) {
390 borrowIn = (*aBlkI == 0);
393 // If there's still a borrow, the result is negative.
394 // Throw an exception, but zero out this object first.
397 throw "BigUnsigned::subtract: Negative result in unsigned calculation";
398 } else // Copy over the rest of the blocks
399 for (; i < a.len; i++, blkI++, aBlkI++)
406 void BigUnsigned::multiply(const BigUnsigned &a, const BigUnsigned &b) {
407 // Block unsafe calls
408 if (this == &a || this == &b)
409 throw "BigUnsigned::multiply: One of the arguments is the invoked object";
410 // If either a or b is zero, set to zero.
411 if (a.len == 0 || b.len == 0) {
415 // Overall method: this = 0, then for each 1-bit of a, add b
416 // to this shifted the appropriate amount.
417 // Variables for the calculation
420 Blk aBlk, bHigh, temp;
421 bool carryIn, carryOut;
422 // These point directly to the positions of interest in the
423 // corresponding block arrays, for faster access.
425 const Blk *aBlkI, *bBlkJ;
426 // Set preliminary length and make room
429 // Zero out this object
430 for (i = 0, blkI = blk; i < len; i++, blkI++)
432 // For each block of the first number...
433 for (i = 0, blkI = blk, aBlkI = a.blk; i < a.len; i++, blkI++, aBlkI++)
434 // For each 1-bit of that block...
435 for (i2 = 0, aBlk = *aBlkI; aBlk != 0; i2++, aBlk >>= 1) {
438 /* Add b to this, shifted left i blocks and i2 bits.
439 * j is the index in b, and k = i + j is the index in this.
440 * The low bits of b.blk[j] are shifted and added to blk[k].
441 * bHigh is used to carry the high bits to the next addition. */
444 for (j = 0, bBlkJ = b.blk, blkK = blkI; j < b.len; j++, bBlkJ++, blkK++) {
445 temp = *blkK + ((*bBlkJ << i2) | bHigh);
446 carryOut = (temp < *blkK);
449 carryOut |= (temp == 0);
453 bHigh = (i2 == 0) ? 0 : *bBlkJ >> (8 * sizeof(Blk) - i2);
455 temp = *blkK + bHigh;
456 carryOut = (temp < *blkK);
459 carryOut |= (temp == 0);
463 for (; carryIn; blkK++) {
465 carryIn = (*blkK == 0);
469 if (blk[len - 1] == 0)
474 void BigUnsigned::divide(const BigUnsigned &a, const BigUnsigned &b) {
475 // Note: This is integer division. Any fractional part
476 // of the result is truncated.
477 // Block unsafe calls
478 if (this == &a || this == &b)
479 throw "BigUnsigned::divide: One of the arguments is the invoked object";
480 // If b is zero, throw an exception. If a is zero, set to zero.
482 throw "BigUnsigned::divide: Division by zero";
483 else if (a.len < b.len) {
487 /* Overall method: Subtract b, shifted varying amounts to
488 * the left, from a, setting the bit in the quotient
489 * whenever the subtraction succeeds. */
490 // Variables for the calculation
494 bool borrowIn, borrowOut;
495 // work1 is a copy of a that can be modified
496 // after each successful subtraction.
497 Blk *work1 = new Blk[a.len + 1];
499 const Blk *aBlkI = a.blk;
500 for (i = 0; i < a.len; i++, work1I++, aBlkI++)
503 // work2 holds part of the result of a subtraction
504 Blk *work2 = new Blk[a.len + 1];
505 // These point directly to the positions of interest in the
506 // corresponding block arrays, for faster access.
507 Blk *blkI, *work1K, *work2J;
509 // Set preliminary length and make room
510 len = a.len - b.len + 1;
512 // For each possible left-shift of b in blocks...
515 work1I = work1 + len;
520 // For each possible left-shift of b in bits...
522 i2 = 8 * sizeof(Blk);
525 // Subtract b, shifted left i blocks and i2 bits, from work1
526 // and store the answer in work2. See note in BigUnsigned::multiply.
528 for (j = 0, bBlkJ = b.blk, work2J = work2, k = i, work1K = work1I,
529 borrowIn = false; j < b.len; j++, bBlkJ++, work2J++, k++, work1K++) {
530 temp = *work1K - ((*bBlkJ << i2) | bHigh);
531 borrowOut = (temp > *work1K);
533 borrowOut |= (temp == 0);
537 borrowIn = borrowOut;
538 bHigh = (i2 == 0) ? 0 : *bBlkJ >> (8 * sizeof(Blk) - i2);
540 temp = *work1K - bHigh;
541 borrowOut = (temp > *work1K);
543 borrowOut |= (temp == 0);
547 borrowIn = borrowOut;
552 for (; k < a.len + 1 && borrowIn; j++, work2J++, k++, work1K++) {
553 borrowIn = (*work1K == 0);
554 *work2J = *work1K - 1;
556 /* If the subtraction was performed successfully, set bit i2
557 * in block i of the quotient, and copy the changed portion of
558 * work2 back to work1. Otherwise, reset that bit and move on. */
572 if (blk[len - 1] == 0)
574 // Deallocate temporary arrays.
575 // (Thanks to Brad Spencer for noticing my accidental omission of this!)
581 void BigUnsigned::modulo(const BigUnsigned &a, const BigUnsigned &b) {
582 /* Note that the mathematical definition of mod is somewhat
583 * different from the way the normal C++ % operator behaves.
584 * This function does it the mathematical way. */
585 // Block unsafe calls
586 if (this == &a || this == &b)
587 throw "BigUnsigned::modulo: One of the arguments is the invoked object";
588 // If b is zero, copy a and return. By the mathematical definition,
589 // x mod 0 = x, though the normal C++ % would throw an exception.
590 else if (b.len == 0) {
593 // If a is zero, set to zero and return.
594 } else if (a.len < b.len) {
598 /* Overall method: Copy a into this. Then subtract b,
599 * shifted varying amounts to the left, from this.
600 * When no more subtraction is possible, stop; this
601 * will contain the remainder.
602 * This is very similar to the division routine, except
603 * that whether or not a subtraction succeeds is ignored,
604 * and "this" serves the purpose of work1. */
605 // Variables for the calculation
609 bool borrowIn, borrowOut;
613 // work2 holds part of the result of a subtraction
614 Blk *work2 = new Blk[a.len + 1];
615 // These point directly to the positions of interest in the
616 // corresponding block arrays, for faster access.
617 Blk *blkI, *blkK, *work2J;
619 // For each possible left-shift of b in blocks...
625 // For each possible left-shift of b in bits...
626 i2 = 8 * sizeof(Blk);
629 // Subtract b, shifted left i blocks and i2 bits, from work1
630 // and store the answer in work2. See note in BigUnsigned::multiply.
632 for (j = 0, bBlkJ = b.blk, work2J = work2, k = i, blkK = blkI,
633 borrowIn = false; j < b.len; j++, bBlkJ++, work2J++, k++, blkK++) {
634 temp = *blkK - ((*bBlkJ << i2) | bHigh);
635 borrowOut = (temp > *blkK);
637 borrowOut |= (temp == 0);
641 borrowIn = borrowOut;
642 bHigh = (i2 == 0) ? 0 : *bBlkJ >> (8 * sizeof(Blk) - i2);
644 temp = *blkK - bHigh;
645 borrowOut = (temp > *blkK);
647 borrowOut |= (temp == 0);
651 borrowIn = borrowOut;
656 for (; k < a.len + 1 && borrowIn; j++, work2J++, k++, blkK++) {
657 borrowIn = (*blkK == 0);
660 // If the subtraction was performed successfully, set bit i2
661 // in block i of the quotient, and copy the changed portion of
662 // work2 back to this.
673 // Blocks higher than the last block of the modulus are zero.
680 void BigUnsigned::bitAnd(const BigUnsigned &a, const BigUnsigned &b) {
681 // Block unsafe calls
682 if (this == &a || this == &b)
683 throw "BigUnsigned::bitAnd: One of the arguments is the invoked object";
684 len = (a.len >= b.len) ? b.len : a.len;
688 const Blk *aBlkI, *bBlkI;
689 for (i = 0, blkI = blk, aBlkI = a.blk, bBlkI = b.blk;
690 i < len; i++, blkI++, aBlkI++, bBlkI++)
691 *blkI = *aBlkI & *bBlkI;
696 void BigUnsigned::bitOr(const BigUnsigned &a, const BigUnsigned &b) {
697 // Block unsafe calls
698 if (this == &a || this == &b)
699 throw "BigUnsigned::bitOr: One of the arguments is the invoked object";
702 const BigUnsigned *a2, *b2;
703 if (a.len >= b.len) {
711 const Blk *a2BlkI, *b2BlkI;
712 for (i = 0, blkI = blk, a2BlkI = a2->blk, b2BlkI = b2->blk;
713 i < b2->len; i++, blkI++, a2BlkI++, b2BlkI++)
714 *blkI = *a2BlkI | *b2BlkI;
715 for (; i < a2->len; i++, blkI++, a2BlkI++)
721 void BigUnsigned::bitXor(const BigUnsigned &a, const BigUnsigned &b) {
722 // Block unsafe calls
723 if (this == &a || this == &b)
724 throw "BigUnsigned::bitXor: One of the arguments is the invoked object";
727 const BigUnsigned *a2, *b2;
728 if (a.len >= b.len) {
736 const Blk *a2BlkI, *b2BlkI;
737 for (i = 0, blkI = blk, a2BlkI = a2->blk, b2BlkI = b2->blk;
738 i < b2->len; i++, blkI++, a2BlkI++, b2BlkI++)
739 *blkI = *a2BlkI ^ *b2BlkI;
740 for (; i < a2->len; i++, blkI++, a2BlkI++)
746 // INCREMENT/DECREMENT OPERATORS
749 void BigUnsigned::operator ++() {
753 for (i = 0, blkI = blk; i < len && carry; i++) {
755 carry = (*blkI == 0);
758 allocateAndCopy(len + 1);
763 // Postfix increment: same as prefix
764 void BigUnsigned::operator ++(int) {
769 void BigUnsigned::operator --() {
771 throw "BigUnsigned::operator --(): Cannot decrement an unsigned zero";
775 for (i = 0, blkI = blk; borrow; i++) {
776 borrow = (*blkI == 0);
779 if (blk[len - 1] == 0)
783 // Postfix decrement: same as prefix
784 void BigUnsigned::operator --(int) {