BigInteger.hh 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215
  1. #ifndef BIGINTEGER_H
  2. #define BIGINTEGER_H
  3. #include "BigUnsigned.hh"
  4. /* A BigInteger object represents a signed integer of size limited only by
  5. * available memory. BigUnsigneds support most mathematical operators and can
  6. * be converted to and from most primitive integer types.
  7. *
  8. * A BigInteger is just an aggregate of a BigUnsigned and a sign. (It is no
  9. * longer derived from BigUnsigned because that led to harmful implicit
  10. * conversions.) */
  11. class BigInteger {
  12. public:
  13. typedef BigUnsigned::Blk Blk;
  14. typedef BigUnsigned::Index Index;
  15. typedef BigUnsigned::CmpRes CmpRes;
  16. static const CmpRes
  17. less = BigUnsigned::less ,
  18. equal = BigUnsigned::equal ,
  19. greater = BigUnsigned::greater;
  20. // Enumeration for the sign of a BigInteger.
  21. enum Sign { negative = -1, zero = 0, positive = 1 };
  22. protected:
  23. Sign sign;
  24. BigUnsigned mag;
  25. public:
  26. // Constructs zero.
  27. BigInteger() : sign(zero), mag() {}
  28. // Copy constructor
  29. BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {};
  30. // Assignment operator
  31. void operator=(const BigInteger &x);
  32. // Constructor that copies from a given array of blocks with a sign.
  33. BigInteger(const Blk *b, Index blen, Sign s);
  34. // Nonnegative constructor that copies from a given array of blocks.
  35. BigInteger(const Blk *b, Index blen) : mag(b, blen) {
  36. sign = mag.isZero() ? zero : positive;
  37. }
  38. // Constructor from a BigUnsigned and a sign
  39. BigInteger(const BigUnsigned &x, Sign s);
  40. // Nonnegative constructor from a BigUnsigned
  41. BigInteger(const BigUnsigned &x) : mag(x) {
  42. sign = mag.isZero() ? zero : positive;
  43. }
  44. // Constructors from primitive integer types
  45. BigInteger(unsigned long x);
  46. BigInteger( long x);
  47. BigInteger(unsigned int x);
  48. BigInteger( int x);
  49. BigInteger(unsigned short x);
  50. BigInteger( short x);
  51. /* Converters to primitive integer types
  52. * The implicit conversion operators caused trouble, so these are now
  53. * named. */
  54. unsigned long toUnsignedLong () const;
  55. long toLong () const;
  56. unsigned int toUnsignedInt () const;
  57. int toInt () const;
  58. unsigned short toUnsignedShort() const;
  59. short toShort () const;
  60. protected:
  61. // Helper
  62. template <class X> X convertToUnsignedPrimitive() const;
  63. template <class X, class UX> X convertToSignedPrimitive() const;
  64. public:
  65. // ACCESSORS
  66. Sign getSign() const { return sign; }
  67. /* The client can't do any harm by holding a read-only reference to the
  68. * magnitude. */
  69. const BigUnsigned &getMagnitude() const { return mag; }
  70. // Some accessors that go through to the magnitude
  71. Index getLength() const { return mag.getLength(); }
  72. Index getCapacity() const { return mag.getCapacity(); }
  73. Blk getBlock(Index i) const { return mag.getBlock(i); }
  74. bool isZero() const { return sign == zero; } // A bit special
  75. // COMPARISONS
  76. // Compares this to x like Perl's <=>
  77. CmpRes compareTo(const BigInteger &x) const;
  78. // Ordinary comparison operators
  79. bool operator ==(const BigInteger &x) const {
  80. return sign == x.sign && mag == x.mag;
  81. }
  82. bool operator !=(const BigInteger &x) const { return !operator ==(x); };
  83. bool operator < (const BigInteger &x) const { return compareTo(x) == less ; }
  84. bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
  85. bool operator >=(const BigInteger &x) const { return compareTo(x) != less ; }
  86. bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
  87. // OPERATORS -- See the discussion in BigUnsigned.hh.
  88. void add (const BigInteger &a, const BigInteger &b);
  89. void subtract(const BigInteger &a, const BigInteger &b);
  90. void multiply(const BigInteger &a, const BigInteger &b);
  91. /* See the comment on BigUnsigned::divideWithRemainder. Semantics
  92. * differ from those of primitive integers when negatives and/or zeros
  93. * are involved. */
  94. void divideWithRemainder(const BigInteger &b, BigInteger &q);
  95. void negate(const BigInteger &a);
  96. /* Bitwise operators are not provided for BigIntegers. Use
  97. * getMagnitude to get the magnitude and operate on that instead. */
  98. BigInteger operator +(const BigInteger &x) const;
  99. BigInteger operator -(const BigInteger &x) const;
  100. BigInteger operator *(const BigInteger &x) const;
  101. BigInteger operator /(const BigInteger &x) const;
  102. BigInteger operator %(const BigInteger &x) const;
  103. BigInteger operator -() const;
  104. void operator +=(const BigInteger &x);
  105. void operator -=(const BigInteger &x);
  106. void operator *=(const BigInteger &x);
  107. void operator /=(const BigInteger &x);
  108. void operator %=(const BigInteger &x);
  109. void flipSign();
  110. // INCREMENT/DECREMENT OPERATORS
  111. void operator ++( );
  112. void operator ++(int);
  113. void operator --( );
  114. void operator --(int);
  115. };
  116. // NORMAL OPERATORS
  117. /* These create an object to hold the result and invoke
  118. * the appropriate put-here operation on it, passing
  119. * this and x. The new object is then returned. */
  120. inline BigInteger BigInteger::operator +(const BigInteger &x) const {
  121. BigInteger ans;
  122. ans.add(*this, x);
  123. return ans;
  124. }
  125. inline BigInteger BigInteger::operator -(const BigInteger &x) const {
  126. BigInteger ans;
  127. ans.subtract(*this, x);
  128. return ans;
  129. }
  130. inline BigInteger BigInteger::operator *(const BigInteger &x) const {
  131. BigInteger ans;
  132. ans.multiply(*this, x);
  133. return ans;
  134. }
  135. inline BigInteger BigInteger::operator /(const BigInteger &x) const {
  136. if (x.isZero()) throw "BigInteger::operator /: division by zero";
  137. BigInteger q, r;
  138. r = *this;
  139. r.divideWithRemainder(x, q);
  140. return q;
  141. }
  142. inline BigInteger BigInteger::operator %(const BigInteger &x) const {
  143. if (x.isZero()) throw "BigInteger::operator %: division by zero";
  144. BigInteger q, r;
  145. r = *this;
  146. r.divideWithRemainder(x, q);
  147. return r;
  148. }
  149. inline BigInteger BigInteger::operator -() const {
  150. BigInteger ans;
  151. ans.negate(*this);
  152. return ans;
  153. }
  154. /*
  155. * ASSIGNMENT OPERATORS
  156. *
  157. * Now the responsibility for making a temporary copy if necessary
  158. * belongs to the put-here operations. See Assignment Operators in
  159. * BigUnsigned.hh.
  160. */
  161. inline void BigInteger::operator +=(const BigInteger &x) {
  162. add(*this, x);
  163. }
  164. inline void BigInteger::operator -=(const BigInteger &x) {
  165. subtract(*this, x);
  166. }
  167. inline void BigInteger::operator *=(const BigInteger &x) {
  168. multiply(*this, x);
  169. }
  170. inline void BigInteger::operator /=(const BigInteger &x) {
  171. if (x.isZero()) throw "BigInteger::operator /=: division by zero";
  172. /* The following technique is slightly faster than copying *this first
  173. * when x is large. */
  174. BigInteger q;
  175. divideWithRemainder(x, q);
  176. // *this contains the remainder, but we overwrite it with the quotient.
  177. *this = q;
  178. }
  179. inline void BigInteger::operator %=(const BigInteger &x) {
  180. if (x.isZero()) throw "BigInteger::operator %=: division by zero";
  181. BigInteger q;
  182. // Mods *this by x. Don't care about quotient left in q.
  183. divideWithRemainder(x, q);
  184. }
  185. // This one is trivial
  186. inline void BigInteger::flipSign() {
  187. sign = Sign(-sign);
  188. }
  189. #endif