Index: third_party/bigint/BigInteger.hh |
diff --git a/third_party/bigint/BigInteger.hh b/third_party/bigint/BigInteger.hh |
new file mode 100644 |
index 0000000000000000000000000000000000000000..cf6e91056f4519a87049993faaab57e2bfbd4177 |
--- /dev/null |
+++ b/third_party/bigint/BigInteger.hh |
@@ -0,0 +1,215 @@ |
+#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 |