| #ifndef BIGINTEGER_H | |
| #define BIGINTEGER_H | |
| #include "BigUnsigned.hh" | |
| /* A BigInteger object represents a signed integer of size limited only by | |
| * available memory. BigUnsigneds support most mathematical operators and can | |
| * be converted to and from most primitive integer types. | |
| * | |
| * A BigInteger is just an aggregate of a BigUnsigned and a sign. (It is no | |
| * longer derived from BigUnsigned because that led to harmful implicit | |
| * conversions.) */ | |
| class BigInteger { | |
| public: | |
| typedef BigUnsigned::Blk Blk; | |
| typedef BigUnsigned::Index Index; | |
| typedef BigUnsigned::CmpRes CmpRes; | |
| static const CmpRes | |
| less = BigUnsigned::less , | |
| equal = BigUnsigned::equal , | |
| greater = BigUnsigned::greater; | |
| // Enumeration for the sign of a BigInteger. | |
| enum Sign { negative = -1, zero = 0, positive = 1 }; | |
| protected: | |
| Sign sign; | |
| BigUnsigned mag; | |
| public: | |
| // Constructs zero. | |
| BigInteger() : sign(zero), mag() {} | |
| // Copy constructor | |
| BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {}; | |
| // Assignment operator | |
| void operator=(const BigInteger &x); | |
| // Constructor that copies from a given array of blocks with a sign. | |
| BigInteger(const Blk *b, Index blen, Sign s); | |
| // Nonnegative constructor that copies from a given array of blocks. | |
| BigInteger(const Blk *b, Index blen) : mag(b, blen) { | |
| sign = mag.isZero() ? zero : positive; | |
| } | |
| // Constructor from a BigUnsigned and a sign | |
| BigInteger(const BigUnsigned &x, Sign s); | |
| // Nonnegative constructor from a BigUnsigned | |
| BigInteger(const BigUnsigned &x) : mag(x) { | |
| sign = mag.isZero() ? zero : positive; | |
| } | |
| // Constructors from primitive integer types | |
| BigInteger(unsigned long x); | |
| BigInteger( long x); | |
| BigInteger(unsigned int x); | |
| BigInteger( int x); | |
| BigInteger(unsigned short x); | |
| BigInteger( short x); | |
| /* Converters to primitive integer types | |
| * The implicit conversion operators caused trouble, so these are now | |
| * named. */ | |
| unsigned long toUnsignedLong () const; | |
| long toLong () const; | |
| unsigned int toUnsignedInt () const; | |
| int toInt () const; | |
| unsigned short toUnsignedShort() const; | |
| short toShort () const; | |
| protected: | |
| // Helper | |
| template <class X> X convertToUnsignedPrimitive() const; | |
| template <class X, class UX> X convertToSignedPrimitive() const; | |
| public: | |
| // ACCESSORS | |
| Sign getSign() const { return sign; } | |
| /* The client can't do any harm by holding a read-only reference to the | |
| * magnitude. */ | |
| const BigUnsigned &getMagnitude() const { return mag; } | |
| // Some accessors that go through to the magnitude | |
| Index getLength() const { return mag.getLength(); } | |
| Index getCapacity() const { return mag.getCapacity(); } | |
| Blk getBlock(Index i) const { return mag.getBlock(i); } | |
| bool isZero() const { return sign == zero; } // A bit special | |
| // COMPARISONS | |
| // Compares this to x like Perl's <=> | |
| CmpRes compareTo(const BigInteger &x) const; | |
| // Ordinary comparison operators | |
| bool operator ==(const BigInteger &x) const { | |
| return sign == x.sign && mag == x.mag; | |
| } | |
| bool operator !=(const BigInteger &x) const { return !operator ==(x); }; | |
| bool operator < (const BigInteger &x) const { return compareTo(x) == less ; } | |
| 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; } | |
| // OPERATORS -- See the discussion in BigUnsigned.hh. | |
| void add (const BigInteger &a, const BigInteger &b); | |
| void subtract(const BigInteger &a, const BigInteger &b); | |
| void multiply(const BigInteger &a, const BigInteger &b); | |
| /* See the comment on BigUnsigned::divideWithRemainder. Semantics | |
| * differ from those of primitive integers when negatives and/or zeros | |
| * are involved. */ | |
| void divideWithRemainder(const BigInteger &b, BigInteger &q); | |
| void negate(const BigInteger &a); | |
| /* Bitwise operators are not provided for BigIntegers. Use | |
| * getMagnitude to get the magnitude and operate on that instead. */ | |
| BigInteger operator +(const BigInteger &x) const; | |
| BigInteger operator -(const BigInteger &x) const; | |
| BigInteger operator *(const BigInteger &x) const; | |
| BigInteger operator /(const BigInteger &x) const; | |
| BigInteger operator %(const BigInteger &x) const; | |
| BigInteger operator -() const; | |
| void operator +=(const BigInteger &x); | |
| void operator -=(const BigInteger &x); | |
| void operator *=(const BigInteger &x); | |
| void operator /=(const BigInteger &x); | |
| void operator %=(const BigInteger &x); | |
| void flipSign(); | |
| // INCREMENT/DECREMENT OPERATORS | |
| void operator ++( ); | |
| void operator ++(int); | |
| void operator --( ); | |
| void operator --(int); | |
| }; | |
| // NORMAL OPERATORS | |
| /* These create an object to hold the result and invoke | |
| * the appropriate put-here operation on it, passing | |
| * this and x. The new object is then returned. */ | |
| inline BigInteger BigInteger::operator +(const BigInteger &x) const { | |
| BigInteger ans; | |
| ans.add(*this, x); | |
| return ans; | |
| } | |
| inline BigInteger BigInteger::operator -(const BigInteger &x) const { | |
| BigInteger ans; | |
| ans.subtract(*this, x); | |
| return ans; | |
| } | |
| inline BigInteger BigInteger::operator *(const BigInteger &x) const { | |
| BigInteger ans; | |
| ans.multiply(*this, x); | |
| return ans; | |
| } | |
| inline BigInteger BigInteger::operator /(const BigInteger &x) const { | |
| if (x.isZero()) throw "BigInteger::operator /: division by zero"; | |
| BigInteger q, r; | |
| r = *this; | |
| r.divideWithRemainder(x, q); | |
| return q; | |
| } | |
| inline BigInteger BigInteger::operator %(const BigInteger &x) const { | |
| if (x.isZero()) throw "BigInteger::operator %: division by zero"; | |
| BigInteger q, r; | |
| r = *this; | |
| r.divideWithRemainder(x, q); | |
| return r; | |
| } | |
| inline BigInteger BigInteger::operator -() const { | |
| BigInteger ans; | |
| ans.negate(*this); | |
| return ans; | |
| } | |
| /* | |
| * 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) { | |
| add(*this, x); | |
| } | |
| inline void BigInteger::operator -=(const BigInteger &x) { | |
| subtract(*this, x); | |
| } | |
| inline void BigInteger::operator *=(const BigInteger &x) { | |
| multiply(*this, x); | |
| } | |
| inline void BigInteger::operator /=(const BigInteger &x) { | |
| if (x.isZero()) throw "BigInteger::operator /=: division by zero"; | |
| /* The following technique is slightly faster than copying *this first | |
| * when x is large. */ | |
| BigInteger q; | |
| divideWithRemainder(x, q); | |
| // *this contains the remainder, but we overwrite it with the quotient. | |
| *this = q; | |
| } | |
| inline void BigInteger::operator %=(const BigInteger &x) { | |
| if (x.isZero()) throw "BigInteger::operator %=: division by zero"; | |
| BigInteger q; | |
| // Mods *this by x. Don't care about quotient left in q. | |
| divideWithRemainder(x, q); | |
| } | |
| // This one is trivial | |
| inline void BigInteger::flipSign() { | |
| sign = Sign(-sign); | |
| } | |
| #endif |