/*
* Matt McCutchen's Big Integer Library
-* http://mysite.verizon.net/mccutchen/bigint/
*/
#ifndef BIGINTEGER
*/
class BigInteger : public BigUnsigned {
-
+
// TYPES & CONSTANTS
public:
enum Sign { negative = -1, zero = 0, positive = 1 }; // Enumeration for the sign of a BigInteger
-
+
// FIELDS
protected:
Sign sign; // The sign of this BigInteger
-
+
// MANAGEMENT
protected:
BigInteger(Sign s, Index c) : BigUnsigned(0, c), sign(s) {}; // Creates a BigInteger with a sign and capacity
BigInteger( short x);
// Note that a BigInteger can be converted to a BigUnsigned
// automatically; this takes its absolute value.
-
+
// CONVERTERS to integral types
public:
operator unsigned long () const;
operator int () const;
operator unsigned short() const;
operator short() const;
-
+
// PICKING APART
// These accessors can be used to get the pieces of the number
public:
Sign getSign() const;
-
+
// COMPARISONS
public:
// Compares this to x like Perl's <=>
bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
bool operator >=(const BigInteger &x) const { return compareTo(x) != less ; }
bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
-
+
// PUT-HERE OPERATIONS
/* These store the result of the operation on the arguments into this.
* a.add(b, c) is equivalent to, but faster than, a = b + c.
- * Calls like a.operation(a, b) are unsafe and not allowed. */
+ * See explanation of "put-here operations" in BigUnsigned.cc . */
public:
void add (const BigInteger &a, const BigInteger &b); // Addition
void subtract(const BigInteger &a, const BigInteger &b); // Subtraction
* and these usually differ from the semantics of primitive-type
* / and % when negatives and/or zeroes are involved.
* Look in `BigInteger.cc' for details.
+ * `a.divideWithRemainder(b, a)' causes an exception: it doesn't make
+ * sense to write quotient and remainder into the same variable.
*/
void divideWithRemainder(const BigInteger &b, BigInteger &q);
void divide(const BigInteger &a, const BigInteger &b) {
- // Division, deprecated and provided for compatibility
BigInteger a2(a);
a2.divideWithRemainder(b, *this);
// quotient now in *this
// don't care about remainder left in a2
}
void modulo(const BigInteger &a, const BigInteger &b) {
- // Modular reduction, deprecated and provided for compatibility
*this = a;
BigInteger q;
divideWithRemainder(b, q);
// redefined for BigIntegers. Calling one of these on
// a BigInteger will convert it to a BigUnsigned,
// which takes its absolute value.
-
+
// NORMAL OPERATORS
// These perform the operation on this (to the left of the operator)
// and x (to the right of the operator) and return a new BigInteger with the result.
BigInteger operator /(const BigInteger &x) const; // Division
BigInteger operator %(const BigInteger &x) const; // Modular reduction
BigInteger operator -( ) const; // Negative
-
+
// ASSIGNMENT OPERATORS
// These perform the operation on this and x, storing the result into this.
public:
void operator /=(const BigInteger &x); // Division
void operator %=(const BigInteger &x); // Modular reduction
void flipSign(); // Negative
-
+
// INCREMENT/DECREMENT OPERATORS
// These increase or decrease the number by 1. To discourage side effects,
// these do not return *this, so prefix and postfix behave the same.
void operator ++(int); // Postfix decrement
void operator --( ); // Prefix increment
void operator --(int); // Postfix decrement
-
+
};
// PICKING APART
return ans;
}
-// ASSIGNMENT OPERATORS
-// These create a copy of this, then invoke the appropriate
-// put-here operation on this, passing the copy and x.
+/*
+ * ASSIGNMENT OPERATORS
+ *
+ * Now the responsibility for making a temporary copy if necessary
+ * belongs to the put-here operations. See Assignment Operators in
+ * BigUnsigned.hh.
+ */
inline void BigInteger::operator +=(const BigInteger &x) {
- BigInteger thisCopy(*this);
- add(thisCopy, x);
+ add(*this, x);
}
inline void BigInteger::operator -=(const BigInteger &x) {
- BigInteger thisCopy(*this);
- subtract(thisCopy, x);
+ subtract(*this, x);
}
inline void BigInteger::operator *=(const BigInteger &x) {
- BigInteger thisCopy(*this);
- multiply(thisCopy, x);
+ multiply(*this, x);
}
inline void BigInteger::operator /=(const BigInteger &x) {
// Updated for divideWithRemainder