1 #include "BigInteger.hh"
6 void BigInteger::operator =(const BigInteger &x) {
7 // Calls like a = a have no effect
13 BigUnsigned::operator =(x);
16 // Constructor from an array of blocks and a sign
17 BigInteger::BigInteger(const Blk *b, Index l, Sign s) : BigUnsigned(b, l) {
22 sign = (len == 0) ? zero : s;
25 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
29 // Constructor from a BigUnsigned and a sign
30 BigInteger::BigInteger(const BigUnsigned &x, Sign s) : BigUnsigned(x) {
35 sign = (len == 0) ? zero : s;
38 throw "BigInteger::BigInteger(Blk *, Index, Sign): Invalid sign";
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.
56 * See remarks in `BigUnsigned.cc' and `NumberlikeArray.hh'
57 * about new handling of zero-length arrays.
60 BigInteger::BigInteger(unsigned long x) {
62 sign = zero; // NumberlikeArray did the rest
72 BigInteger::BigInteger(long x) {
89 BigInteger::BigInteger(unsigned int x) {
101 BigInteger::BigInteger(int x) {
118 BigInteger::BigInteger(unsigned short x) {
130 BigInteger::BigInteger(short x) {
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.
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;
178 BigInteger::operator unsigned long() const {
186 throw "BigInteger operator unsigned long() const: Value is too big for an unsigned long";
188 throw "BigInteger operator unsigned long() const: Cannot convert a negative integer to an unsigned type";
190 throw "BigInteger: Internal error";
194 BigInteger::operator long() const {
199 if (len == 1 && (blk[0] & ~lMask) == 0)
202 throw "BigInteger operator long() const: Value is too big for a long";
204 if (len == 1 && (blk[0] & ~lMask) == 0)
205 return -long(blk[0]);
207 throw "BigInteger operator long() const: Value is too big for a long";
209 throw "BigInteger: Internal error";
213 BigInteger::operator unsigned int() const {
218 if (len == 1 && (blk[0] & ~uiMask) == 0)
219 return (unsigned int)(blk[0]);
221 throw "BigInteger operator unsigned int() const: Value is too big for an unsigned int";
223 throw "BigInteger operator unsigned int() const: Cannot convert a negative integer to an unsigned type";
225 throw "BigInteger: Internal error";
229 BigInteger::operator int() const {
234 if (len == 1 && (blk[0] & ~iMask) == 0)
237 throw "BigInteger operator int() const: Value is too big for an int";
239 if (len == 1 && (blk[0] & ~iMask) == 0)
242 throw "BigInteger operator int() const: Value is too big for an int";
244 throw "BigInteger: Internal error";
248 BigInteger::operator unsigned short() const {
253 if (len == 1 && (blk[0] & ~usMask) == 0)
254 return (unsigned short)(blk[0]);
256 throw "BigInteger operator unsigned short() const: Value is too big for an unsigned short";
258 throw "BigInteger operator unsigned short() const: Cannot convert a negative integer to an unsigned type";
260 throw "BigInteger: Internal error";
264 BigInteger::operator short() const {
269 if (len == 1 && (blk[0] & ~sMask) == 0)
270 return short(blk[0]);
272 throw "BigInteger operator short() const: Value is too big for a short";
274 if (len == 1 && (blk[0] & ~sMask) == 0)
275 return -short(blk[0]);
277 throw "BigInteger operator short() const: Value is too big for a short";
279 throw "BigInteger: Internal error";
284 BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
285 // A greater sign implies a greater number
288 else if (sign > x.sign)
291 // If the signs are the same...
293 return equal; // Two zeros are equal
295 // Compare the magnitudes
296 return BigUnsigned::compareTo(x);
298 // Compare the magnitudes, but return the opposite result
299 return CmpRes(-BigUnsigned::compareTo(x));
301 throw "BigInteger: Internal error";
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.
309 // See remarks about aliased calls in BigUnsigned.cc .
310 #define DTRT_ALIASED(cond, op) \
312 BigInteger tmpThis; \
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.
324 else if (b.sign == zero)
326 // If the arguments have the same sign, take the
327 // common sign and add their magnitudes.
328 else if (a.sign == b.sign) {
330 BigUnsigned::add(a, b);
332 // Otherwise, their magnitudes must be compared.
333 switch (a.BigUnsigned::compareTo(b)) {
334 // If their magnitudes are the same, copy zero.
339 // Otherwise, take the sign of the greater, and subtract
340 // the lesser magnitude from the greater magnitude.
343 BigUnsigned::subtract(a, b);
347 BigUnsigned::subtract(b, a);
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)
366 // If their signs differ, take a.sign and add the magnitudes.
367 else if (a.sign != b.sign) {
369 BigUnsigned::add(a, b);
371 // Otherwise, their magnitudes must be compared.
372 switch (a.BigUnsigned::compareTo(b)) {
373 // If their magnitudes are the same, copy zero.
378 // If a's magnitude is greater, take a.sign and
379 // subtract a from b.
382 BigUnsigned::subtract(a, b);
384 // If b's magnitude is greater, take the opposite
385 // of b.sign and subtract b from a.
387 sign = Sign(-b.sign);
388 BigUnsigned::subtract(b, a);
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) {
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);
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.
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).
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.
424 * Examples: (q = a / b, r = a % b)
432 void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
433 // Defend against aliased calls;
434 // same idea as in BigUnsigned::divideWithRemainder .
436 throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
437 if (this == &b || &q == &b) {
439 divideWithRemainder(tmpB, q);
443 // Division by zero gives quotient 0 and remainder *this
444 if (b.sign == zero) {
449 // 0 / b gives quotient 0 and remainder 0
456 // Here *this != 0, b != 0.
458 // Do the operands have the same sign?
459 if (sign == b.sign) {
460 // Yes: easy case. Quotient is zero or positive.
463 // No: harder case. Quotient is negative.
465 // Decrease the magnitude of the dividend by one.
466 BigUnsigned::operator --();
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:
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.
489 // Divide the magnitudes.
490 BigUnsigned::divideWithRemainder(b, q);
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 --();
502 // Sign of the remainder is always the sign of the divisor b.
505 // Set signs to zero as necessary. (Thanks David Allen!)
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);
523 // INCREMENT/DECREMENT OPERATORS
526 void BigInteger::operator ++() {
535 BigUnsigned::operator ++();
538 BigUnsigned::operator --();
545 // Postfix increment: same as prefix
546 void BigInteger::operator ++(int) {
551 void BigInteger::operator --() {
560 BigUnsigned::operator ++();
563 BigUnsigned::operator --();
570 // Postfix decrement: same as prefix
571 void BigInteger::operator --(int) {