BigInteger.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405
  1. #include "BigInteger.hh"
  2. void BigInteger::operator =(const BigInteger &x) {
  3. // Calls like a = a have no effect
  4. if (this == &x)
  5. return;
  6. // Copy sign
  7. sign = x.sign;
  8. // Copy the rest
  9. mag = x.mag;
  10. }
  11. BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
  12. switch (s) {
  13. case zero:
  14. if (!mag.isZero())
  15. throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude";
  16. sign = zero;
  17. break;
  18. case positive:
  19. case negative:
  20. // If the magnitude is zero, force the sign to zero.
  21. sign = mag.isZero() ? zero : s;
  22. break;
  23. default:
  24. /* g++ seems to be optimizing out this case on the assumption
  25. * that the sign is a valid member of the enumeration. Oh well. */
  26. throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign";
  27. }
  28. }
  29. BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
  30. switch (s) {
  31. case zero:
  32. if (!mag.isZero())
  33. throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude";
  34. sign = zero;
  35. break;
  36. case positive:
  37. case negative:
  38. // If the magnitude is zero, force the sign to zero.
  39. sign = mag.isZero() ? zero : s;
  40. break;
  41. default:
  42. /* g++ seems to be optimizing out this case on the assumption
  43. * that the sign is a valid member of the enumeration. Oh well. */
  44. throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign";
  45. }
  46. }
  47. /* CONSTRUCTION FROM PRIMITIVE INTEGERS
  48. * Same idea as in BigUnsigned.cc, except that negative input results in a
  49. * negative BigInteger instead of an exception. */
  50. // Done longhand to let us use initialization.
  51. BigInteger::BigInteger(unsigned long x) : mag(x) { sign = mag.isZero() ? zero : positive; }
  52. BigInteger::BigInteger(unsigned int x) : mag(x) { sign = mag.isZero() ? zero : positive; }
  53. BigInteger::BigInteger(unsigned short x) : mag(x) { sign = mag.isZero() ? zero : positive; }
  54. // For signed input, determine the desired magnitude and sign separately.
  55. namespace {
  56. template <class X, class UX>
  57. BigInteger::Blk magOf(X x) {
  58. /* UX(...) cast needed to stop short(-2^15), which negates to
  59. * itself, from sign-extending in the conversion to Blk. */
  60. return BigInteger::Blk(x < 0 ? UX(-x) : x);
  61. }
  62. template <class X>
  63. BigInteger::Sign signOf(X x) {
  64. return (x == 0) ? BigInteger::zero
  65. : (x > 0) ? BigInteger::positive
  66. : BigInteger::negative;
  67. }
  68. }
  69. BigInteger::BigInteger(long x) : sign(signOf(x)), mag(magOf<long , unsigned long >(x)) {}
  70. BigInteger::BigInteger(int x) : sign(signOf(x)), mag(magOf<int , unsigned int >(x)) {}
  71. BigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf<short, unsigned short>(x)) {}
  72. // CONVERSION TO PRIMITIVE INTEGERS
  73. /* Reuse BigUnsigned's conversion to an unsigned primitive integer.
  74. * The friend is a separate function rather than
  75. * BigInteger::convertToUnsignedPrimitive to avoid requiring BigUnsigned to
  76. * declare BigInteger. */
  77. template <class X>
  78. inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) {
  79. return a.convertToPrimitive<X>();
  80. }
  81. template <class X>
  82. X BigInteger::convertToUnsignedPrimitive() const {
  83. if (sign == negative)
  84. throw "BigInteger::to<Primitive>: "
  85. "Cannot convert a negative integer to an unsigned type";
  86. else
  87. return convertBigUnsignedToPrimitiveAccess<X>(mag);
  88. }
  89. /* Similar to BigUnsigned::convertToPrimitive, but split into two cases for
  90. * nonnegative and negative numbers. */
  91. template <class X, class UX>
  92. X BigInteger::convertToSignedPrimitive() const {
  93. if (sign == zero)
  94. return 0;
  95. else if (mag.getLength() == 1) {
  96. // The single block might fit in an X. Try the conversion.
  97. Blk b = mag.getBlock(0);
  98. if (sign == positive) {
  99. X x = X(b);
  100. if (x >= 0 && Blk(x) == b)
  101. return x;
  102. } else {
  103. X x = -X(b);
  104. /* UX(...) needed to avoid rejecting conversion of
  105. * -2^15 to a short. */
  106. if (x < 0 && Blk(UX(-x)) == b)
  107. return x;
  108. }
  109. // Otherwise fall through.
  110. }
  111. throw "BigInteger::to<Primitive>: "
  112. "Value is too big to fit in the requested type";
  113. }
  114. unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive<unsigned long > (); }
  115. unsigned int BigInteger::toUnsignedInt () const { return convertToUnsignedPrimitive<unsigned int > (); }
  116. unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive<unsigned short> (); }
  117. long BigInteger::toLong () const { return convertToSignedPrimitive <long , unsigned long> (); }
  118. int BigInteger::toInt () const { return convertToSignedPrimitive <int , unsigned int> (); }
  119. short BigInteger::toShort () const { return convertToSignedPrimitive <short, unsigned short>(); }
  120. // COMPARISON
  121. BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
  122. // A greater sign implies a greater number
  123. if (sign < x.sign)
  124. return less;
  125. else if (sign > x.sign)
  126. return greater;
  127. else switch (sign) {
  128. // If the signs are the same...
  129. case zero:
  130. return equal; // Two zeros are equal
  131. case positive:
  132. // Compare the magnitudes
  133. return mag.compareTo(x.mag);
  134. case negative:
  135. // Compare the magnitudes, but return the opposite result
  136. return CmpRes(-mag.compareTo(x.mag));
  137. default:
  138. throw "BigInteger internal error";
  139. }
  140. }
  141. /* COPY-LESS OPERATIONS
  142. * These do some messing around to determine the sign of the result,
  143. * then call one of BigUnsigned's copy-less operations. */
  144. // See remarks about aliased calls in BigUnsigned.cc .
  145. #define DTRT_ALIASED(cond, op) \
  146. if (cond) { \
  147. BigInteger tmpThis; \
  148. tmpThis.op; \
  149. *this = tmpThis; \
  150. return; \
  151. }
  152. void BigInteger::add(const BigInteger &a, const BigInteger &b) {
  153. DTRT_ALIASED(this == &a || this == &b, add(a, b));
  154. // If one argument is zero, copy the other.
  155. if (a.sign == zero)
  156. operator =(b);
  157. else if (b.sign == zero)
  158. operator =(a);
  159. // If the arguments have the same sign, take the
  160. // common sign and add their magnitudes.
  161. else if (a.sign == b.sign) {
  162. sign = a.sign;
  163. mag.add(a.mag, b.mag);
  164. } else {
  165. // Otherwise, their magnitudes must be compared.
  166. switch (a.mag.compareTo(b.mag)) {
  167. case equal:
  168. // If their magnitudes are the same, copy zero.
  169. mag = 0;
  170. sign = zero;
  171. break;
  172. // Otherwise, take the sign of the greater, and subtract
  173. // the lesser magnitude from the greater magnitude.
  174. case greater:
  175. sign = a.sign;
  176. mag.subtract(a.mag, b.mag);
  177. break;
  178. case less:
  179. sign = b.sign;
  180. mag.subtract(b.mag, a.mag);
  181. break;
  182. }
  183. }
  184. }
  185. void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
  186. // Notice that this routine is identical to BigInteger::add,
  187. // if one replaces b.sign by its opposite.
  188. DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
  189. // If a is zero, copy b and flip its sign. If b is zero, copy a.
  190. if (a.sign == zero) {
  191. mag = b.mag;
  192. // Take the negative of _b_'s, sign, not ours.
  193. // Bug pointed out by Sam Larkin on 2005.03.30.
  194. sign = Sign(-b.sign);
  195. } else if (b.sign == zero)
  196. operator =(a);
  197. // If their signs differ, take a.sign and add the magnitudes.
  198. else if (a.sign != b.sign) {
  199. sign = a.sign;
  200. mag.add(a.mag, b.mag);
  201. } else {
  202. // Otherwise, their magnitudes must be compared.
  203. switch (a.mag.compareTo(b.mag)) {
  204. // If their magnitudes are the same, copy zero.
  205. case equal:
  206. mag = 0;
  207. sign = zero;
  208. break;
  209. // If a's magnitude is greater, take a.sign and
  210. // subtract a from b.
  211. case greater:
  212. sign = a.sign;
  213. mag.subtract(a.mag, b.mag);
  214. break;
  215. // If b's magnitude is greater, take the opposite
  216. // of b.sign and subtract b from a.
  217. case less:
  218. sign = Sign(-b.sign);
  219. mag.subtract(b.mag, a.mag);
  220. break;
  221. }
  222. }
  223. }
  224. void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
  225. DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
  226. // If one object is zero, copy zero and return.
  227. if (a.sign == zero || b.sign == zero) {
  228. sign = zero;
  229. mag = 0;
  230. return;
  231. }
  232. // If the signs of the arguments are the same, the result
  233. // is positive, otherwise it is negative.
  234. sign = (a.sign == b.sign) ? positive : negative;
  235. // Multiply the magnitudes.
  236. mag.multiply(a.mag, b.mag);
  237. }
  238. /*
  239. * DIVISION WITH REMAINDER
  240. * Please read the comments before the definition of
  241. * `BigUnsigned::divideWithRemainder' in `BigUnsigned.cc' for lots of
  242. * information you should know before reading this function.
  243. *
  244. * Following Knuth, I decree that x / y is to be
  245. * 0 if y==0 and floor(real-number x / y) if y!=0.
  246. * Then x % y shall be x - y*(integer x / y).
  247. *
  248. * Note that x = y * (x / y) + (x % y) always holds.
  249. * In addition, (x % y) is from 0 to y - 1 if y > 0,
  250. * and from -(|y| - 1) to 0 if y < 0. (x % y) = x if y = 0.
  251. *
  252. * Examples: (q = a / b, r = a % b)
  253. * a b q r
  254. * === === === ===
  255. * 4 3 1 1
  256. * -4 3 -2 2
  257. * 4 -3 -2 -2
  258. * -4 -3 1 -1
  259. */
  260. void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
  261. // Defend against aliased calls;
  262. // same idea as in BigUnsigned::divideWithRemainder .
  263. if (this == &q)
  264. throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
  265. if (this == &b || &q == &b) {
  266. BigInteger tmpB(b);
  267. divideWithRemainder(tmpB, q);
  268. return;
  269. }
  270. // Division by zero gives quotient 0 and remainder *this
  271. if (b.sign == zero) {
  272. q.mag = 0;
  273. q.sign = zero;
  274. return;
  275. }
  276. // 0 / b gives quotient 0 and remainder 0
  277. if (sign == zero) {
  278. q.mag = 0;
  279. q.sign = zero;
  280. return;
  281. }
  282. // Here *this != 0, b != 0.
  283. // Do the operands have the same sign?
  284. if (sign == b.sign) {
  285. // Yes: easy case. Quotient is zero or positive.
  286. q.sign = positive;
  287. } else {
  288. // No: harder case. Quotient is negative.
  289. q.sign = negative;
  290. // Decrease the magnitude of the dividend by one.
  291. mag--;
  292. /*
  293. * We tinker with the dividend before and with the
  294. * quotient and remainder after so that the result
  295. * comes out right. To see why it works, consider the following
  296. * list of examples, where A is the magnitude-decreased
  297. * a, Q and R are the results of BigUnsigned division
  298. * with remainder on A and |b|, and q and r are the
  299. * final results we want:
  300. *
  301. * a A b Q R q r
  302. * -3 -2 3 0 2 -1 0
  303. * -4 -3 3 1 0 -2 2
  304. * -5 -4 3 1 1 -2 1
  305. * -6 -5 3 1 2 -2 0
  306. *
  307. * It appears that we need a total of 3 corrections:
  308. * Decrease the magnitude of a to get A. Increase the
  309. * magnitude of Q to get q (and make it negative).
  310. * Find r = (b - 1) - R and give it the desired sign.
  311. */
  312. }
  313. // Divide the magnitudes.
  314. mag.divideWithRemainder(b.mag, q.mag);
  315. if (sign != b.sign) {
  316. // More for the harder case (as described):
  317. // Increase the magnitude of the quotient by one.
  318. q.mag++;
  319. // Modify the remainder.
  320. mag.subtract(b.mag, mag);
  321. mag--;
  322. }
  323. // Sign of the remainder is always the sign of the divisor b.
  324. sign = b.sign;
  325. // Set signs to zero as necessary. (Thanks David Allen!)
  326. if (mag.isZero())
  327. sign = zero;
  328. if (q.mag.isZero())
  329. q.sign = zero;
  330. // WHEW!!!
  331. }
  332. // Negation
  333. void BigInteger::negate(const BigInteger &a) {
  334. DTRT_ALIASED(this == &a, negate(a));
  335. // Copy a's magnitude
  336. mag = a.mag;
  337. // Copy the opposite of a.sign
  338. sign = Sign(-a.sign);
  339. }
  340. // INCREMENT/DECREMENT OPERATORS
  341. // Prefix increment
  342. void BigInteger::operator ++() {
  343. if (sign == negative) {
  344. mag--;
  345. if (mag == 0)
  346. sign = zero;
  347. } else {
  348. mag++;
  349. sign = positive; // if not already
  350. }
  351. }
  352. // Postfix increment: same as prefix
  353. void BigInteger::operator ++(int) {
  354. operator ++();
  355. }
  356. // Prefix decrement
  357. void BigInteger::operator --() {
  358. if (sign == positive) {
  359. mag--;
  360. if (mag == 0)
  361. sign = zero;
  362. } else {
  363. mag++;
  364. sign = negative;
  365. }
  366. }
  367. // Postfix decrement: same as prefix
  368. void BigInteger::operator --(int) {
  369. operator --();
  370. }