fork download
  1. #include<iostream>
  2. #include<string>
  3. using namespace std;
  4. template <class Blk>
  5. class NumberlikeArray {
  6. public:
  7. typedef unsigned int Index;
  8. static const unsigned int N;
  9. Index cap;
  10. Index len;
  11. Blk *blk;
  12. NumberlikeArray(Index c) : cap(c), len(0) { blk = (cap > 0) ? (new Blk[cap]) : NULL;}
  13. NumberlikeArray() : cap(0), len(0) {blk = NULL;}
  14. ~NumberlikeArray() {delete [] blk;}
  15. void allocate(Index c);
  16. void allocateAndCopy(Index c);
  17. NumberlikeArray(const NumberlikeArray<Blk> &x);
  18. void operator=(const NumberlikeArray<Blk> &x);
  19. NumberlikeArray(const Blk *b, Index blen);
  20. Index getCapacity() const { return cap; }
  21. Index getLength() const { return len; }
  22. Blk getBlock(Index i) const { return blk[i]; }
  23. bool isEmpty() const { return len == 0; }
  24. bool operator ==(const NumberlikeArray<Blk> &x) const;
  25. bool operator !=(const NumberlikeArray<Blk> &x) const { return !operator ==(x); }
  26. };
  27. template <class Blk>
  28. const unsigned int NumberlikeArray<Blk>::N = 8 * sizeof(Blk);
  29. template <class Blk>
  30. void NumberlikeArray<Blk>::allocate(Index c) {if (c > cap) {delete [] blk;cap = c;blk = new Blk[cap];}}
  31. template <class Blk>
  32. void NumberlikeArray<Blk>::allocateAndCopy(Index c) {if (c > cap) {Blk *oldBlk = blk;cap = c;blk = new Blk[cap];Index i;
  33. for (i = 0; i < len; i++)
  34. blk[i] = oldBlk[i];
  35. delete [] oldBlk;
  36. }
  37. }
  38. template <class Blk>
  39. NumberlikeArray<Blk>::NumberlikeArray(const NumberlikeArray<Blk> &x)
  40. : len(x.len) {
  41. cap = len;
  42. blk = new Blk[cap];
  43. Index i;
  44. for (i = 0; i < len; i++)
  45. blk[i] = x.blk[i];
  46. }
  47. template <class Blk>
  48. void NumberlikeArray<Blk>::operator=(const NumberlikeArray<Blk> &x) {
  49. if (this == &x)
  50. return;
  51. len = x.len;
  52. allocate(len);
  53. Index i;
  54. for (i = 0; i < len; i++)
  55. blk[i] = x.blk[i];
  56. }
  57. template <class Blk>
  58. NumberlikeArray<Blk>::NumberlikeArray(const Blk *b, Index blen)
  59. : cap(blen), len(blen) {
  60. blk = new Blk[cap];
  61. Index i;
  62. for (i = 0; i < len; i++)
  63. blk[i] = b[i];
  64. }
  65. template <class Blk>
  66. bool NumberlikeArray<Blk>::operator ==(const NumberlikeArray<Blk> &x) const {
  67. if (len != x.len)
  68. return false;
  69. else {
  70. Index i;
  71. for (i = 0; i < len; i++)
  72. if (blk[i] != x.blk[i])
  73. return false;
  74. return true;
  75. }
  76. }
  77. class BigUnsigned : protected NumberlikeArray<unsigned long> {
  78. public:
  79. enum CmpRes { less = -1, equal = 0, greater = 1 };
  80. typedef unsigned long Blk;
  81. typedef NumberlikeArray<Blk>::Index Index;
  82. NumberlikeArray<Blk>::N;
  83. protected:
  84. BigUnsigned(int, Index c) : NumberlikeArray<Blk>(0, c) {}
  85. void zapLeadingZeros() {
  86. while (len > 0 && blk[len - 1] == 0)
  87. len--;
  88. }
  89. public:
  90. BigUnsigned() : NumberlikeArray<Blk>() {}
  91. BigUnsigned(const BigUnsigned &x) : NumberlikeArray<Blk>(x) {}
  92. void operator=(const BigUnsigned &x) {
  93. NumberlikeArray<Blk>::operator =(x);
  94. }
  95. BigUnsigned(const Blk *b, Index blen) : NumberlikeArray<Blk>(b, blen) {
  96. zapLeadingZeros();
  97. }
  98. ~BigUnsigned() {}
  99. BigUnsigned(unsigned long x);
  100. BigUnsigned( long x);
  101. BigUnsigned(unsigned int x);
  102. BigUnsigned( int x);
  103. BigUnsigned(unsigned short x);
  104. BigUnsigned( short x);
  105. protected:
  106. template <class X> void initFromPrimitive (X x);
  107. template <class X> void initFromSignedPrimitive(X x);
  108. public:
  109. unsigned long toUnsignedLong () const;
  110. long toLong () const;
  111. unsigned int toUnsignedInt () const;
  112. int toInt () const;
  113. unsigned short toUnsignedShort() const;
  114. short toShort () const;
  115. protected:
  116. template <class X> X convertToSignedPrimitive() const;
  117. template <class X> X convertToPrimitive () const;
  118. public:
  119. NumberlikeArray<Blk>::getCapacity;
  120. NumberlikeArray<Blk>::getLength;
  121. Blk getBlock(Index i) const { return i >= len ? 0 : blk[i]; }
  122. void setBlock(Index i, Blk newBlock);
  123. bool isZero() const { return NumberlikeArray<Blk>::isEmpty(); }
  124. Index bitLength() const;
  125. bool getBit(Index bi) const {return (getBlock(bi / N) & (Blk(1) << (bi % N))) != 0;}
  126. void setBit(Index bi, bool newBit);
  127. CmpRes compareTo(const BigUnsigned &x) const;
  128. bool operator ==(const BigUnsigned &x) const {return NumberlikeArray<Blk>::operator ==(x);}
  129. bool operator !=(const BigUnsigned &x) const {return NumberlikeArray<Blk>::operator !=(x);}
  130. bool operator < (const BigUnsigned &x) const { return compareTo(x) == less ; }
  131. bool operator <=(const BigUnsigned &x) const { return compareTo(x) != greater; }
  132. bool operator >=(const BigUnsigned &x) const { return compareTo(x) != less ; }
  133. bool operator > (const BigUnsigned &x) const { return compareTo(x) == greater; }
  134. void add(const BigUnsigned &a, const BigUnsigned &b);
  135. void subtract(const BigUnsigned &a, const BigUnsigned &b);
  136. void multiply(const BigUnsigned &a, const BigUnsigned &b);
  137. void bitAnd(const BigUnsigned &a, const BigUnsigned &b);
  138. void bitOr(const BigUnsigned &a, const BigUnsigned &b);
  139. void bitXor(const BigUnsigned &a, const BigUnsigned &b);
  140. void bitShiftLeft(const BigUnsigned &a, int b);
  141. void bitShiftRight(const BigUnsigned &a, int b);
  142. void divideWithRemainder(const BigUnsigned &b, BigUnsigned &q);
  143. BigUnsigned operator +(const BigUnsigned &x) const;
  144. BigUnsigned operator -(const BigUnsigned &x) const;
  145. BigUnsigned operator *(const BigUnsigned &x) const;
  146. BigUnsigned operator /(const BigUnsigned &x) const;
  147. BigUnsigned operator %(const BigUnsigned &x) const;
  148. BigUnsigned operator &(const BigUnsigned &x) const;
  149. BigUnsigned operator |(const BigUnsigned &x) const;
  150. BigUnsigned operator ^(const BigUnsigned &x) const;
  151. BigUnsigned operator <<(int b) const;
  152. BigUnsigned operator >>(int b) const;
  153. void operator +=(const BigUnsigned &x);
  154. void operator -=(const BigUnsigned &x);
  155. void operator *=(const BigUnsigned &x);
  156. void operator /=(const BigUnsigned &x);
  157. void operator %=(const BigUnsigned &x);
  158. void operator &=(const BigUnsigned &x);
  159. void operator |=(const BigUnsigned &x);
  160. void operator ^=(const BigUnsigned &x);
  161. void operator <<=(int b);
  162. void operator >>=(int b);
  163. void operator ++( );
  164. void operator ++(int);
  165. void operator --( );
  166. void operator --(int);
  167. friend Blk getShiftedBlock(const BigUnsigned &num, Index x,unsigned int y);
  168. template <class X>
  169. friend X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a);
  170. };
  171. inline BigUnsigned BigUnsigned::operator +(const BigUnsigned &x) const {BigUnsigned ans;ans.add(*this, x);return ans;}
  172. inline BigUnsigned BigUnsigned::operator -(const BigUnsigned &x) const {BigUnsigned ans;ans.subtract(*this, x);return ans;}
  173. inline BigUnsigned BigUnsigned::operator *(const BigUnsigned &x) const {BigUnsigned ans;ans.multiply(*this, x);return ans;}
  174. inline BigUnsigned BigUnsigned::operator /(const BigUnsigned &x) const {if (x.isZero()) throw "BigUnsigned::operator /: division by zero";
  175. BigUnsigned q, r;
  176. r = *this;
  177. r.divideWithRemainder(x, q);
  178. return q;
  179. }
  180. inline BigUnsigned BigUnsigned::operator %(const BigUnsigned &x) const {
  181. if (x.isZero()) throw "BigUnsigned::operator %: division by zero";
  182. BigUnsigned q, r;
  183. r = *this;
  184. r.divideWithRemainder(x, q);
  185. return r;
  186. }
  187. inline BigUnsigned BigUnsigned::operator &(const BigUnsigned &x) const {BigUnsigned ans;ans.bitAnd(*this, x);return ans;}
  188. inline BigUnsigned BigUnsigned::operator |(const BigUnsigned &x) const {BigUnsigned ans;ans.bitOr(*this, x);return ans;}
  189. inline BigUnsigned BigUnsigned::operator ^(const BigUnsigned &x) const {BigUnsigned ans;ans.bitXor(*this, x);return ans;}
  190. inline BigUnsigned BigUnsigned::operator <<(int b) const {BigUnsigned ans;ans.bitShiftLeft(*this, b);return ans;}
  191. inline BigUnsigned BigUnsigned::operator >>(int b) const {BigUnsigned ans;ans.bitShiftRight(*this, b);return ans;}
  192. inline void BigUnsigned::operator +=(const BigUnsigned &x) {add(*this, x);}
  193. inline void BigUnsigned::operator -=(const BigUnsigned &x) {subtract(*this, x);}
  194. inline void BigUnsigned::operator *=(const BigUnsigned &x) {multiply(*this, x);}
  195. inline void BigUnsigned::operator /=(const BigUnsigned &x) {if (x.isZero()) throw "BigUnsigned::operator /=: division by zero";
  196. BigUnsigned q;
  197. divideWithRemainder(x, q);
  198. *this = q;
  199. }
  200. inline void BigUnsigned::operator %=(const BigUnsigned &x) {if (x.isZero()) throw "BigUnsigned::operator %=: division by zero";
  201. BigUnsigned q;
  202. divideWithRemainder(x, q);
  203. }
  204. inline void BigUnsigned::operator &=(const BigUnsigned &x) {bitAnd(*this, x);}
  205. inline void BigUnsigned::operator |=(const BigUnsigned &x) {bitOr(*this, x);}
  206. inline void BigUnsigned::operator ^=(const BigUnsigned &x) {bitXor(*this, x);}
  207. inline void BigUnsigned::operator <<=(int b) {bitShiftLeft(*this, b);}
  208. inline void BigUnsigned::operator >>=(int b) {bitShiftRight(*this, b);}
  209. template <class X>
  210. void BigUnsigned::initFromPrimitive(X x) {
  211. if (x == 0)
  212. ;
  213. else {
  214. cap = 1;
  215. blk = new Blk[1];
  216. len = 1;
  217. blk[0] = Blk(x);
  218. }
  219. }
  220. template <class X>
  221. void BigUnsigned::initFromSignedPrimitive(X x) {
  222. if (x < 0)
  223. throw "BigUnsigned constructor: "
  224. "Cannot construct a BigUnsigned from a negative number";
  225. else
  226. initFromPrimitive(x);
  227. }
  228. template <class X>
  229. X BigUnsigned::convertToPrimitive() const {
  230. if (len == 0)
  231. return 0;
  232. else if (len == 1) {
  233. X x = X(blk[0]);
  234. if (Blk(x) == blk[0])
  235. return x;
  236. }
  237. throw "BigUnsigned::to<Primitive>: "
  238. "Value is too big to fit in the requested type";
  239. }
  240. template <class X>
  241. X BigUnsigned::convertToSignedPrimitive() const {
  242. X x = convertToPrimitive<X>();
  243. if (x >= 0)
  244. return x;
  245. else
  246. throw "BigUnsigned::to(Primitive): "
  247. "Value is too big to fit in the requested type";
  248. }
  249. class BigInteger {
  250. public:
  251. typedef BigUnsigned::Blk Blk;
  252. typedef BigUnsigned::Index Index;
  253. typedef BigUnsigned::CmpRes CmpRes;
  254. static const CmpRes
  255. less = BigUnsigned::less ,
  256. equal = BigUnsigned::equal ,
  257. greater = BigUnsigned::greater;
  258. enum Sign { negative = -1, zero = 0, positive = 1 };
  259.  
  260. protected:
  261. Sign sign;
  262. BigUnsigned mag;
  263.  
  264. public:
  265. BigInteger() : sign(zero), mag() {}
  266. BigInteger(const BigInteger &x) : sign(x.sign), mag(x.mag) {};
  267. void operator=(const BigInteger &x);
  268. BigInteger(const Blk *b, Index blen, Sign s);
  269. BigInteger(const Blk *b, Index blen) : mag(b, blen) {
  270. sign = mag.isZero() ? zero : positive;
  271. }
  272. BigInteger(const BigUnsigned &x, Sign s);
  273. BigInteger(const BigUnsigned &x) : mag(x) {
  274. sign = mag.isZero() ? zero : positive;
  275. }
  276. BigInteger(unsigned long x);
  277. BigInteger( long x);
  278. BigInteger(unsigned int x);
  279. BigInteger( int x);
  280. BigInteger(unsigned short x);
  281. BigInteger( short x);
  282. unsigned long toUnsignedLong () const;
  283. long toLong () const;
  284. unsigned int toUnsignedInt () const;
  285. int toInt () const;
  286. unsigned short toUnsignedShort() const;
  287. short toShort () const;
  288. protected:
  289. template <class X> X convertToUnsignedPrimitive() const;
  290. template <class X, class UX> X convertToSignedPrimitive() const;
  291. public:
  292. Sign getSign() const { return sign; }
  293. const BigUnsigned &getMagnitude() const { return mag; }
  294. Index getLength() const { return mag.getLength(); }
  295. Index getCapacity() const { return mag.getCapacity(); }
  296. Blk getBlock(Index i) const { return mag.getBlock(i); }
  297. bool isZero() const { return sign == zero; }
  298. CmpRes compareTo(const BigInteger &x) const;
  299. bool operator ==(const BigInteger &x) const {
  300. return sign == x.sign && mag == x.mag;
  301. }
  302. bool operator !=(const BigInteger &x) const { return !operator ==(x); };
  303. bool operator < (const BigInteger &x) const { return compareTo(x) == less ; }
  304. bool operator <=(const BigInteger &x) const { return compareTo(x) != greater; }
  305. bool operator >=(const BigInteger &x) const { return compareTo(x) != less ; }
  306. bool operator > (const BigInteger &x) const { return compareTo(x) == greater; }
  307. void add (const BigInteger &a, const BigInteger &b);
  308. void subtract(const BigInteger &a, const BigInteger &b);
  309. void multiply(const BigInteger &a, const BigInteger &b);
  310. void divideWithRemainder(const BigInteger &b, BigInteger &q);
  311. void negate(const BigInteger &a);
  312. BigInteger operator +(const BigInteger &x) const;
  313. BigInteger operator -(const BigInteger &x) const;
  314. BigInteger operator *(const BigInteger &x) const;
  315. BigInteger operator /(const BigInteger &x) const;
  316. BigInteger operator %(const BigInteger &x) const;
  317. BigInteger operator -() const;
  318. void operator +=(const BigInteger &x);
  319. void operator -=(const BigInteger &x);
  320. void operator *=(const BigInteger &x);
  321. void operator /=(const BigInteger &x);
  322. void operator %=(const BigInteger &x);
  323. void flipSign();
  324. void operator ++( );
  325. void operator ++(int);
  326. void operator --( );
  327. void operator --(int);
  328. };
  329. inline BigInteger BigInteger::operator +(const BigInteger &x) const {
  330. BigInteger ans;
  331. ans.add(*this, x);
  332. return ans;
  333. }
  334. inline BigInteger BigInteger::operator -(const BigInteger &x) const {
  335. BigInteger ans;
  336. ans.subtract(*this, x);
  337. return ans;
  338. }
  339. inline BigInteger BigInteger::operator *(const BigInteger &x) const {
  340. BigInteger ans;
  341. ans.multiply(*this, x);
  342. return ans;
  343. }
  344. inline BigInteger BigInteger::operator /(const BigInteger &x) const {
  345. if (x.isZero()) throw "BigInteger::operator /: division by zero";
  346. BigInteger q, r;
  347. r = *this;
  348. r.divideWithRemainder(x, q);
  349. return q;
  350. }
  351. inline BigInteger BigInteger::operator %(const BigInteger &x) const {
  352. if (x.isZero()) throw "BigInteger::operator %: division by zero";
  353. BigInteger q, r;
  354. r = *this;
  355. r.divideWithRemainder(x, q);
  356. return r;
  357. }
  358. inline BigInteger BigInteger::operator -() const {
  359. BigInteger ans;
  360. ans.negate(*this);
  361. return ans;
  362. }
  363. inline void BigInteger::operator +=(const BigInteger &x) {
  364. add(*this, x);
  365. }
  366. inline void BigInteger::operator -=(const BigInteger &x) {
  367. subtract(*this, x);
  368. }
  369. inline void BigInteger::operator *=(const BigInteger &x) {
  370. multiply(*this, x);
  371. }
  372. inline void BigInteger::operator /=(const BigInteger &x) {
  373. if (x.isZero()) throw "BigInteger::operator /=: division by zero";
  374. BigInteger q;
  375. divideWithRemainder(x, q);
  376. *this = q;
  377. }
  378. inline void BigInteger::operator %=(const BigInteger &x) {
  379. if (x.isZero()) throw "BigInteger::operator %=: division by zero";
  380. BigInteger q;
  381. divideWithRemainder(x, q);
  382. }
  383. inline void BigInteger::flipSign() {
  384. sign = Sign(-sign);
  385. }
  386. BigUnsigned gcd(BigUnsigned a, BigUnsigned b);
  387. void extendedEuclidean(BigInteger m, BigInteger n,
  388. BigInteger &g, BigInteger &r, BigInteger &s);
  389. BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n);
  390. BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
  391. const BigUnsigned &modulus);
  392. class BigUnsignedInABase : protected NumberlikeArray<unsigned short> {
  393. public:
  394. typedef unsigned short Digit;
  395. typedef Digit Base;
  396. protected:
  397. Base base;
  398. BigUnsignedInABase(int, Index c) : NumberlikeArray<Digit>(0, c) {}
  399. void zapLeadingZeros() {
  400. while (len > 0 && blk[len - 1] == 0)
  401. len--;
  402. }
  403. public:
  404. BigUnsignedInABase() : NumberlikeArray<Digit>(), base(2) {}
  405. BigUnsignedInABase(const BigUnsignedInABase &x) : NumberlikeArray<Digit>(x), base(x.base) {}
  406. void operator =(const BigUnsignedInABase &x) {
  407. NumberlikeArray<Digit>::operator =(x);
  408. base = x.base;
  409. }
  410. BigUnsignedInABase(const Digit *d, Index l, Base base);
  411. ~BigUnsignedInABase() {}
  412. BigUnsignedInABase(const BigUnsigned &x, Base base);
  413. operator BigUnsigned() const;
  414. operator std::string() const;
  415. BigUnsignedInABase(const std::string &s, Base base);
  416.  
  417. public:
  418. Base getBase() const { return base; }
  419. NumberlikeArray<Digit>::getCapacity;
  420. NumberlikeArray<Digit>::getLength;
  421. Digit getDigit(Index i) const { return i >= len ? 0 : blk[i]; }
  422. bool isZero() const { return NumberlikeArray<Digit>::isEmpty(); }
  423. bool operator ==(const BigUnsignedInABase &x) const {
  424. return base == x.base && NumberlikeArray<Digit>::operator ==(x);
  425. }
  426. bool operator !=(const BigUnsignedInABase &x) const { return !operator ==(x); }
  427. };
  428. std::string bigUnsignedToString(const BigUnsigned &x);
  429. std::string bigIntegerToString(const BigInteger &x);
  430. BigUnsigned stringToBigUnsigned(const std::string &s);
  431. BigInteger stringToBigInteger(const std::string &s);
  432. template <class T>
  433. BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign);
  434. std::ostream &operator <<(std::ostream &os, const BigUnsigned &x);
  435. std::ostream &operator <<(std::ostream &os, const BigInteger &x);
  436. template <class T>
  437. BigInteger dataToBigInteger(const T* data, BigInteger::Index length, BigInteger::Sign sign) {
  438. unsigned int pieceSizeInBits = 8 * sizeof(T);
  439. unsigned int piecesPerBlock = sizeof(BigInteger::Blk) / sizeof(T);
  440. unsigned int numBlocks = (length + piecesPerBlock - 1) / piecesPerBlock;
  441. BigInteger::Blk *blocks = new BigInteger::Blk[numBlocks];
  442. BigInteger::Index blockNum, pieceNum, pieceNumHere;
  443. for (blockNum = 0, pieceNum = 0; blockNum < numBlocks; blockNum++) {
  444. BigInteger::Blk curBlock = 0;
  445. for (pieceNumHere = 0; pieceNumHere < piecesPerBlock && pieceNum < length;
  446. pieceNumHere++, pieceNum++)
  447. curBlock |= (BigInteger::Blk(data[pieceNum]) << (pieceSizeInBits * pieceNumHere));
  448. blocks[blockNum] = curBlock;
  449. }
  450. BigInteger x(blocks, numBlocks, sign);
  451. delete [] blocks;
  452. return x;
  453. }
  454. BigUnsigned::BigUnsigned(unsigned long x) { initFromPrimitive (x); }
  455. BigUnsigned::BigUnsigned(unsigned int x) { initFromPrimitive (x); }
  456. BigUnsigned::BigUnsigned(unsigned short x) { initFromPrimitive (x); }
  457. BigUnsigned::BigUnsigned( long x) { initFromSignedPrimitive(x); }
  458. BigUnsigned::BigUnsigned( int x) { initFromSignedPrimitive(x); }
  459. BigUnsigned::BigUnsigned( short x) { initFromSignedPrimitive(x); }
  460. unsigned long BigUnsigned::toUnsignedLong () const { return convertToPrimitive <unsigned long >(); }
  461. unsigned int BigUnsigned::toUnsignedInt () const { return convertToPrimitive <unsigned int >(); }
  462. unsigned short BigUnsigned::toUnsignedShort() const { return convertToPrimitive <unsigned short>(); }
  463. long BigUnsigned::toLong () const { return convertToSignedPrimitive< long >(); }
  464. int BigUnsigned::toInt () const { return convertToSignedPrimitive< int >(); }
  465. short BigUnsigned::toShort () const { return convertToSignedPrimitive< short>(); }
  466. void BigUnsigned::setBlock(Index i, Blk newBlock) {
  467. if (newBlock == 0) {
  468. if (i < len) {
  469. blk[i] = 0;
  470. zapLeadingZeros();
  471. }
  472. } else {
  473. if (i >= len) {
  474. allocateAndCopy(i+1);
  475. for (Index j = len; j < i; j++)
  476. blk[j] = 0;
  477. len = i+1;
  478. }
  479. blk[i] = newBlock;
  480. }
  481. }
  482. BigUnsigned::Index BigUnsigned::bitLength() const {
  483. if (isZero())
  484. return 0;
  485. else {
  486. Blk leftmostBlock = getBlock(len - 1);
  487. Index leftmostBlockLen = 0;
  488. while (leftmostBlock != 0) {
  489. leftmostBlock >>= 1;
  490. leftmostBlockLen++;
  491. }
  492. return leftmostBlockLen + (len - 1) * N;
  493. }
  494. }
  495. void BigUnsigned::setBit(Index bi, bool newBit) {
  496. Index blockI = bi / N;
  497. Blk block = getBlock(blockI), mask = Blk(1) << (bi % N);
  498. block = newBit ? (block | mask) : (block & ~mask);
  499. setBlock(blockI, block);
  500. }
  501. BigUnsigned::CmpRes BigUnsigned::compareTo(const BigUnsigned &x) const {
  502. if (len < x.len)
  503. return less;
  504. else if (len > x.len)
  505. return greater;
  506. else {
  507. Index i = len;
  508. while (i > 0) {
  509. i--;
  510. if (blk[i] == x.blk[i])
  511. continue;
  512. else if (blk[i] > x.blk[i])
  513. return greater;
  514. else
  515. return less;
  516. }
  517. return equal;
  518. }
  519. }
  520. #define DTRT_ALIASED(cond, op) \
  521. if (cond) { \
  522. BigUnsigned tmpThis; \
  523. tmpThis.op; \
  524. *this = tmpThis; \
  525. return; \
  526. }
  527. void BigUnsigned::add(const BigUnsigned &a, const BigUnsigned &b) {
  528. DTRT_ALIASED(this == &a || this == &b, add(a, b));
  529. if (a.len == 0) {
  530. operator =(b);
  531. return;
  532. } else if (b.len == 0) {
  533. operator =(a);
  534. return;
  535. }
  536. bool carryIn, carryOut;
  537. Blk temp;
  538. Index i;
  539. const BigUnsigned *a2, *b2;
  540. if (a.len >= b.len) {
  541. a2 = &a;
  542. b2 = &b;
  543. } else {
  544. a2 = &b;
  545. b2 = &a;
  546. }
  547. len = a2->len + 1;
  548. allocate(len);
  549. for (i = 0, carryIn = false; i < b2->len; i++) {
  550. temp = a2->blk[i] + b2->blk[i];
  551. carryOut = (temp < a2->blk[i]);
  552. if (carryIn) {
  553. temp++;
  554. carryOut |= (temp == 0);
  555. }
  556. blk[i] = temp;
  557. carryIn = carryOut;
  558. }
  559. for (; i < a2->len && carryIn; i++) {
  560. temp = a2->blk[i] + 1;
  561. carryIn = (temp == 0);
  562. blk[i] = temp;
  563. }
  564. for (; i < a2->len; i++)
  565. blk[i] = a2->blk[i];
  566. if (carryIn)
  567. blk[i] = 1;
  568. else
  569. len--;
  570. }
  571. void BigUnsigned::subtract(const BigUnsigned &a, const BigUnsigned &b) {
  572. DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
  573. if (b.len == 0) {
  574. operator =(a);
  575. return;
  576. } else if (a.len < b.len)
  577. throw "BigUnsigned::subtract: "
  578. "Negative result in unsigned calculation";
  579. bool borrowIn, borrowOut;
  580. Blk temp;
  581. Index i;
  582. len = a.len;
  583. allocate(len);
  584. for (i = 0, borrowIn = false; i < b.len; i++) {
  585. temp = a.blk[i] - b.blk[i];
  586. borrowOut = (temp > a.blk[i]);
  587. if (borrowIn) {
  588. borrowOut |= (temp == 0);
  589. temp--;
  590. }
  591. blk[i] = temp;
  592. borrowIn = borrowOut;
  593. }
  594. for (; i < a.len && borrowIn; i++) {
  595. borrowIn = (a.blk[i] == 0);
  596. blk[i] = a.blk[i] - 1;
  597. }
  598. if (borrowIn) {
  599. len = 0;
  600. throw "BigUnsigned::subtract: Negative result in unsigned calculation";
  601. }
  602. else
  603. for (; i < a.len; i++)
  604. blk[i] = a.blk[i];
  605. zapLeadingZeros();
  606. }
  607. inline BigUnsigned::Blk getShiftedBlock(const BigUnsigned &num,
  608. BigUnsigned::Index x, unsigned int y) {
  609. BigUnsigned::Blk part1 = (x == 0 || y == 0) ? 0 : (num.blk[x - 1] >> (BigUnsigned::N - y));
  610. BigUnsigned::Blk part2 = (x == num.len) ? 0 : (num.blk[x] << y);
  611. return part1 | part2;
  612. }
  613. void BigUnsigned::multiply(const BigUnsigned &a, const BigUnsigned &b) {
  614. DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
  615. if (a.len == 0 || b.len == 0) {
  616. len = 0;
  617. return;
  618. }
  619. Index i, j, k;
  620. unsigned int i2;
  621. Blk temp;
  622. bool carryIn, carryOut;
  623. len = a.len + b.len;
  624. allocate(len);
  625. for (i = 0; i < len; i++)
  626. blk[i] = 0;
  627. for (i = 0; i < a.len; i++) {
  628. for (i2 = 0; i2 < N; i2++) {
  629. if ((a.blk[i] & (Blk(1) << i2)) == 0)
  630. continue;
  631. for (j = 0, k = i, carryIn = false; j <= b.len; j++, k++) {
  632. temp = blk[k] + getShiftedBlock(b, j, i2);
  633. carryOut = (temp < blk[k]);
  634. if (carryIn) {
  635. temp++;
  636. carryOut |= (temp == 0);
  637. }
  638. blk[k] = temp;
  639. carryIn = carryOut;
  640. }
  641. for (; carryIn; k++) {
  642. blk[k]++;
  643. carryIn = (blk[k] == 0);
  644. }
  645. }
  646. }
  647. if (blk[len - 1] == 0)
  648. len--;
  649. }
  650. void BigUnsigned::divideWithRemainder(const BigUnsigned &b, BigUnsigned &q) {
  651. if (this == &q)
  652. throw "BigUnsigned::divideWithRemainder: Cannot write quotient and remainder into the same variable";
  653. if (this == &b || &q == &b) {
  654. BigUnsigned tmpB(b);
  655. divideWithRemainder(tmpB, q);
  656. return;
  657. }
  658. if (b.len == 0) {
  659. q.len = 0;
  660. return;
  661. }
  662. if (len < b.len) {
  663. q.len = 0;
  664. return;
  665. }
  666. Index i, j, k;
  667. unsigned int i2;
  668. Blk temp;
  669. bool borrowIn, borrowOut;
  670. Index origLen = len;
  671. allocateAndCopy(len + 1);
  672. len++;
  673. blk[origLen] = 0;
  674. Blk *subtractBuf = new Blk[len];
  675. q.len = origLen - b.len + 1;
  676. q.allocate(q.len);
  677. for (i = 0; i < q.len; i++)
  678. q.blk[i] = 0;
  679. i = q.len;
  680. while (i > 0) {
  681. i--;
  682. q.blk[i] = 0;
  683. i2 = N;
  684. while (i2 > 0) {
  685. i2--;
  686. for (j = 0, k = i, borrowIn = false; j <= b.len; j++, k++) {
  687. temp = blk[k] - getShiftedBlock(b, j, i2);
  688. borrowOut = (temp > blk[k]);
  689. if (borrowIn) {
  690. borrowOut |= (temp == 0);
  691. temp--;
  692. }
  693. subtractBuf[k] = temp;
  694. borrowIn = borrowOut;
  695. }
  696. for (; k < origLen && borrowIn; k++) {
  697. borrowIn = (blk[k] == 0);
  698. subtractBuf[k] = blk[k] - 1;
  699. }
  700. if (!borrowIn) {
  701. q.blk[i] |= (Blk(1) << i2);
  702. while (k > i) {
  703. k--;
  704. blk[k] = subtractBuf[k];
  705. }
  706. }
  707. }
  708. }
  709. if (q.blk[q.len - 1] == 0)
  710. q.len--;
  711. zapLeadingZeros();
  712. delete [] subtractBuf;
  713. }
  714. void BigUnsigned::bitAnd(const BigUnsigned &a, const BigUnsigned &b) {
  715. DTRT_ALIASED(this == &a || this == &b, bitAnd(a, b));
  716. len = (a.len >= b.len) ? b.len : a.len;
  717. allocate(len);
  718. Index i;
  719. for (i = 0; i < len; i++)
  720. blk[i] = a.blk[i] & b.blk[i];
  721. zapLeadingZeros();
  722. }
  723. void BigUnsigned::bitOr(const BigUnsigned &a, const BigUnsigned &b) {
  724. DTRT_ALIASED(this == &a || this == &b, bitOr(a, b));
  725. Index i;
  726. const BigUnsigned *a2, *b2;
  727. if (a.len >= b.len) {
  728. a2 = &a;
  729. b2 = &b;
  730. } else {
  731. a2 = &b;
  732. b2 = &a;
  733. }
  734. allocate(a2->len);
  735. for (i = 0; i < b2->len; i++)
  736. blk[i] = a2->blk[i] | b2->blk[i];
  737. for (; i < a2->len; i++)
  738. blk[i] = a2->blk[i];
  739. len = a2->len;
  740. }
  741. void BigUnsigned::bitXor(const BigUnsigned &a, const BigUnsigned &b) {
  742. DTRT_ALIASED(this == &a || this == &b, bitXor(a, b));
  743. Index i;
  744. const BigUnsigned *a2, *b2;
  745. if (a.len >= b.len) {
  746. a2 = &a;
  747. b2 = &b;
  748. } else {
  749. a2 = &b;
  750. b2 = &a;
  751. }
  752. allocate(a2->len);
  753. for (i = 0; i < b2->len; i++)
  754. blk[i] = a2->blk[i] ^ b2->blk[i];
  755. for (; i < a2->len; i++)
  756. blk[i] = a2->blk[i];
  757. len = a2->len;
  758. zapLeadingZeros();
  759. }
  760. void BigUnsigned::bitShiftLeft(const BigUnsigned &a, int b) {
  761. DTRT_ALIASED(this == &a, bitShiftLeft(a, b));
  762. if (b < 0) {
  763. if (b << 1 == 0)
  764. throw "BigUnsigned::bitShiftLeft: "
  765. "Pathological shift amount not implemented";
  766. else {
  767. bitShiftRight(a, -b);
  768. return;
  769. }
  770. }
  771. Index shiftBlocks = b / N;
  772. unsigned int shiftBits = b % N;
  773. len = a.len + shiftBlocks + 1;
  774. allocate(len);
  775. Index i, j;
  776. for (i = 0; i < shiftBlocks; i++)
  777. blk[i] = 0;
  778. for (j = 0, i = shiftBlocks; j <= a.len; j++, i++)
  779. blk[i] = getShiftedBlock(a, j, shiftBits);
  780. if (blk[len - 1] == 0)
  781. len--;
  782. }
  783. void BigUnsigned::bitShiftRight(const BigUnsigned &a, int b) {
  784. DTRT_ALIASED(this == &a, bitShiftRight(a, b));
  785. if (b < 0) {
  786. if (b << 1 == 0)
  787. throw "BigUnsigned::bitShiftRight: "
  788. "Pathological shift amount not implemented";
  789. else {
  790. bitShiftLeft(a, -b);
  791. return;
  792. }
  793. }
  794. Index rightShiftBlocks = (b + N - 1) / N;
  795. unsigned int leftShiftBits = N * rightShiftBlocks - b;
  796. if (rightShiftBlocks >= a.len + 1) {
  797. len = 0;
  798. return;
  799. }
  800. len = a.len + 1 - rightShiftBlocks;
  801. allocate(len);
  802. Index i, j;
  803. for (j = rightShiftBlocks, i = 0; j <= a.len; j++, i++)
  804. blk[i] = getShiftedBlock(a, j, leftShiftBits);
  805. if (blk[len - 1] == 0)
  806. len--;
  807. }
  808. void BigUnsigned::operator ++() {
  809. Index i;
  810. bool carry = true;
  811. for (i = 0; i < len && carry; i++) {
  812. blk[i]++;
  813. carry = (blk[i] == 0);
  814. }
  815. if (carry) {
  816. allocateAndCopy(len + 1);
  817. len++;
  818. blk[i] = 1;
  819. }
  820. }
  821. void BigUnsigned::operator ++(int) {
  822. operator ++();
  823. }
  824. void BigUnsigned::operator --() {
  825. if (len == 0)
  826. throw "BigUnsigned::operator --(): Cannot decrement an unsigned zero";
  827. Index i;
  828. bool borrow = true;
  829. for (i = 0; borrow; i++) {
  830. borrow = (blk[i] == 0);
  831. blk[i]--;
  832. }
  833. if (blk[len - 1] == 0)
  834. len--;
  835. }
  836. void BigUnsigned::operator --(int) {
  837. operator --();
  838. }
  839. void BigInteger::operator =(const BigInteger &x) {
  840. if (this == &x)
  841. return;
  842. sign = x.sign;
  843. mag = x.mag;
  844. }
  845. BigInteger::BigInteger(const Blk *b, Index blen, Sign s) : mag(b, blen) {
  846. switch (s) {
  847. case zero:
  848. if (!mag.isZero())
  849. throw "BigInteger::BigInteger(const Blk *, Index, Sign): Cannot use a sign of zero with a nonzero magnitude";
  850. sign = zero;
  851. break;
  852. case positive:
  853. case negative:
  854. sign = mag.isZero() ? zero : s;
  855. break;
  856. default:
  857. throw "BigInteger::BigInteger(const Blk *, Index, Sign): Invalid sign";
  858. }
  859. }
  860. BigInteger::BigInteger(const BigUnsigned &x, Sign s) : mag(x) {
  861. switch (s) {
  862. case zero:
  863. if (!mag.isZero())
  864. throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Cannot use a sign of zero with a nonzero magnitude";
  865. sign = zero;
  866. break;
  867. case positive:
  868. case negative:
  869. sign = mag.isZero() ? zero : s;
  870. break;
  871. default:
  872. throw "BigInteger::BigInteger(const BigUnsigned &, Sign): Invalid sign";
  873. }
  874. }
  875. BigInteger::BigInteger(unsigned long x) : mag(x) { sign = mag.isZero() ? zero : positive; }
  876. BigInteger::BigInteger(unsigned int x) : mag(x) { sign = mag.isZero() ? zero : positive; }
  877. BigInteger::BigInteger(unsigned short x) : mag(x) { sign = mag.isZero() ? zero : positive; }
  878. namespace {
  879. template <class X, class UX>
  880. BigInteger::Blk magOf(X x) {
  881. return BigInteger::Blk(x < 0 ? UX(-x) : x);
  882. }
  883. template <class X>
  884. BigInteger::Sign signOf(X x) {
  885. return (x == 0) ? BigInteger::zero
  886. : (x > 0) ? BigInteger::positive
  887. : BigInteger::negative;
  888. }
  889. }
  890. BigInteger::BigInteger(long x) : sign(signOf(x)), mag(magOf<long , unsigned long >(x)) {}
  891. BigInteger::BigInteger(int x) : sign(signOf(x)), mag(magOf<int , unsigned int >(x)) {}
  892. BigInteger::BigInteger(short x) : sign(signOf(x)), mag(magOf<short, unsigned short>(x)) {}
  893. template <class X>
  894. inline X convertBigUnsignedToPrimitiveAccess(const BigUnsigned &a) {
  895. return a.convertToPrimitive<X>();
  896. }
  897. template <class X>
  898. X BigInteger::convertToUnsignedPrimitive() const {
  899. if (sign == negative)
  900. throw "BigInteger::to<Primitive>: "
  901. "Cannot convert a negative integer to an unsigned type";
  902. else
  903. return convertBigUnsignedToPrimitiveAccess<X>(mag);
  904. }
  905. template <class X, class UX>
  906. X BigInteger::convertToSignedPrimitive() const {
  907. if (sign == zero)
  908. return 0;
  909. else if (mag.getLength() == 1) {Blk b = mag.getBlock(0);if (sign == positive) { X x = X(b); if (x >= 0 && Blk(x) == b) return x;}
  910. else {X x = -X(b);if (x < 0 && Blk(UX(-x)) == b)return x;}
  911. }
  912. throw "BigInteger::to<Primitive>: "
  913. "Value is too big to fit in the requested type";
  914. }
  915. unsigned long BigInteger::toUnsignedLong () const { return convertToUnsignedPrimitive<unsigned long > (); }
  916. unsigned int BigInteger::toUnsignedInt () const { return convertToUnsignedPrimitive<unsigned int > (); }
  917. unsigned short BigInteger::toUnsignedShort() const { return convertToUnsignedPrimitive<unsigned short> (); }
  918. long BigInteger::toLong () const { return convertToSignedPrimitive <long , unsigned long> (); }
  919. int BigInteger::toInt () const { return convertToSignedPrimitive <int , unsigned int> (); }
  920. short BigInteger::toShort () const { return convertToSignedPrimitive <short, unsigned short>(); }
  921. BigInteger::CmpRes BigInteger::compareTo(const BigInteger &x) const {
  922. if (sign < x.sign)
  923. return less;
  924. else if (sign > x.sign)
  925. return greater;
  926. else switch (sign) {
  927. case zero:
  928. return equal;
  929. case positive:
  930. return mag.compareTo(x.mag);
  931. case negative:
  932. return CmpRes(-mag.compareTo(x.mag));
  933. default:
  934. throw "BigInteger internal error";
  935. }
  936. }
  937. #define DTRT_ALIASED(cond, op) \
  938. if (cond) { \
  939. BigInteger tmpThis; \
  940. tmpThis.op; \
  941. *this = tmpThis; \
  942. return; \
  943. }
  944. void BigInteger::add(const BigInteger &a, const BigInteger &b) {
  945. DTRT_ALIASED(this == &a || this == &b, add(a, b));
  946. if (a.sign == zero)
  947. operator =(b);
  948. else if (b.sign == zero)
  949. operator =(a);
  950. else if (a.sign == b.sign) {sign = a.sign; mag.add(a.mag, b.mag);}
  951. else { switch (a.mag.compareTo(b.mag)) {
  952. case equal:
  953. mag = 0;
  954. sign = zero;
  955. break;
  956. case greater:
  957. sign = a.sign;
  958. mag.subtract(a.mag, b.mag);
  959. break;
  960. case less:
  961. sign = b.sign;
  962. mag.subtract(b.mag, a.mag);
  963. break;
  964. }
  965. }
  966. }
  967. void BigInteger::subtract(const BigInteger &a, const BigInteger &b) {
  968. DTRT_ALIASED(this == &a || this == &b, subtract(a, b));
  969. if (a.sign == zero) {
  970. mag = b.mag;
  971. sign = Sign(-b.sign);
  972. } else if (b.sign == zero)
  973. operator =(a);
  974. else if (a.sign != b.sign) { sign = a.sign; mag.add(a.mag, b.mag); }
  975. else { switch (a.mag.compareTo(b.mag)) { case equal: mag = 0; sign = zero; break;
  976. case greater:
  977. sign = a.sign;
  978. mag.subtract(a.mag, b.mag);
  979. break;
  980. case less:
  981. sign = Sign(-b.sign);
  982. mag.subtract(b.mag, a.mag);
  983. break;
  984. }
  985. }
  986. }
  987. void BigInteger::multiply(const BigInteger &a, const BigInteger &b) {
  988. DTRT_ALIASED(this == &a || this == &b, multiply(a, b));
  989. if (a.sign == zero || b.sign == zero) { sign = zero; mag = 0; return; }
  990. sign = (a.sign == b.sign) ? positive : negative;
  991. mag.multiply(a.mag, b.mag);
  992. }
  993.  
  994. void BigInteger::divideWithRemainder(const BigInteger &b, BigInteger &q) {
  995. if (this == &q)
  996. throw "BigInteger::divideWithRemainder: Cannot write quotient and remainder into the same variable";
  997. if (this == &b || &q == &b) {
  998. BigInteger tmpB(b);
  999. divideWithRemainder(tmpB, q);
  1000. return;
  1001. }
  1002. if (b.sign == zero) { q.mag = 0; q.sign = zero; return; }
  1003. if (sign == zero) { q.mag = 0; q.sign = zero; return; }
  1004. if (sign == b.sign) { q.sign = positive; }
  1005. else { q.sign = negative; mag--;}
  1006. mag.divideWithRemainder(b.mag, q.mag);
  1007. if (sign != b.sign) {
  1008. q.mag++;
  1009. mag.subtract(b.mag, mag);
  1010. mag--;
  1011. }
  1012. sign = b.sign;
  1013. if (mag.isZero()) sign = zero;
  1014. if (q.mag.isZero()) q.sign = zero;
  1015. }
  1016. void BigInteger::negate(const BigInteger &a) {
  1017. DTRT_ALIASED(this == &a, negate(a));
  1018. mag = a.mag;
  1019. sign = Sign(-a.sign);
  1020. }
  1021. void BigInteger::operator ++() {
  1022. if (sign == negative) {
  1023. mag--;
  1024. if (mag == 0)
  1025. sign = zero;
  1026. } else {
  1027. mag++;
  1028. sign = positive;
  1029. }
  1030. }
  1031. void BigInteger::operator ++(int) {
  1032. operator ++();
  1033. }
  1034. void BigInteger::operator --() {
  1035. if (sign == positive) {
  1036. mag--;
  1037. if (mag == 0)
  1038. sign = zero;
  1039. } else {
  1040. mag++;
  1041. sign = negative;
  1042. }
  1043. }
  1044. void BigInteger::operator --(int) {
  1045. operator --();
  1046. }
  1047. BigUnsigned gcd(BigUnsigned a, BigUnsigned b) {
  1048. BigUnsigned trash;
  1049. for (;;) {
  1050. if (b.isZero())
  1051. return a;
  1052. a.divideWithRemainder(b, trash);
  1053. if (a.isZero())
  1054. return b;
  1055. b.divideWithRemainder(a, trash);
  1056. }
  1057. }
  1058. void extendedEuclidean(BigInteger m, BigInteger n,
  1059. BigInteger &g, BigInteger &r, BigInteger &s) {
  1060. if (&g == &r || &g == &s || &r == &s)
  1061. throw "BigInteger extendedEuclidean: Outputs are aliased";
  1062. BigInteger r1(1), s1(0), r2(0), s2(1), q;
  1063. for (;;) {
  1064. if (n.isZero()) {
  1065. r = r1; s = s1; g = m;
  1066. return;
  1067. }
  1068. m.divideWithRemainder(n, q);
  1069. r1 -= q*r2; s1 -= q*s2;
  1070.  
  1071. if (m.isZero()) {
  1072. r = r2; s = s2; g = n;
  1073. return;
  1074. }
  1075. n.divideWithRemainder(m, q);
  1076. r2 -= q*r1; s2 -= q*s1;
  1077. }
  1078. }
  1079. BigUnsigned modinv(const BigInteger &x, const BigUnsigned &n) {
  1080. BigInteger g, r, s;
  1081. extendedEuclidean(x, n, g, r, s);
  1082. if (g == 1)
  1083. return (r % n).getMagnitude();
  1084. else
  1085. throw "BigInteger modinv: x and n have a common factor";
  1086. }
  1087. BigUnsigned modexp(const BigInteger &base, const BigUnsigned &exponent,
  1088. const BigUnsigned &modulus) {
  1089. BigUnsigned ans = 1, base2 = (base % modulus).getMagnitude();
  1090. BigUnsigned::Index i = exponent.bitLength();
  1091. while (i > 0) {
  1092. i--;
  1093. ans *= ans;
  1094. ans %= modulus;
  1095. if (exponent.getBit(i)) {
  1096. ans *= base2;
  1097. ans %= modulus;
  1098. }
  1099. }
  1100. return ans;
  1101. }
  1102. BigUnsignedInABase::BigUnsignedInABase(const Digit *d, Index l, Base base)
  1103. : NumberlikeArray<Digit>(d, l), base(base) {
  1104. if (base < 2)
  1105. throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): The base must be at least 2";
  1106. for (Index i = 0; i < l; i++)
  1107. if (blk[i] >= base)
  1108. throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): A digit is too large for the specified base";
  1109. zapLeadingZeros();
  1110. }
  1111. namespace {
  1112. unsigned int bitLen(unsigned int x) {
  1113. unsigned int len = 0;
  1114. while (x > 0) {
  1115. x >>= 1;
  1116. len++;
  1117. }
  1118. return len;
  1119. }
  1120. unsigned int ceilingDiv(unsigned int a, unsigned int b) {
  1121. return (a + b - 1) / b;
  1122. }
  1123. }
  1124. BigUnsignedInABase::BigUnsignedInABase(const BigUnsigned &x, Base base) {
  1125. if (base < 2)
  1126. throw "BigUnsignedInABase(BigUnsigned, Base): The base must be at least 2";
  1127. this->base = base;
  1128. int maxBitLenOfX = x.getLength() * BigUnsigned::N;
  1129. int minBitsPerDigit = bitLen(base) - 1;
  1130. int maxDigitLenOfX = ceilingDiv(maxBitLenOfX, minBitsPerDigit);
  1131. len = maxDigitLenOfX;
  1132. allocate(len);
  1133. BigUnsigned x2(x), buBase(base);
  1134. Index digitNum = 0;
  1135. while (!x2.isZero()) {
  1136. BigUnsigned lastDigit(x2);
  1137. lastDigit.divideWithRemainder(buBase, x2);
  1138. blk[digitNum] = lastDigit.toUnsignedShort();
  1139. digitNum++;
  1140. }
  1141. len = digitNum;
  1142. }
  1143. BigUnsignedInABase::operator BigUnsigned() const {
  1144. BigUnsigned ans(0), buBase(base), temp;
  1145. Index digitNum = len;
  1146. while (digitNum > 0) {
  1147. digitNum--;
  1148. temp.multiply(ans, buBase);
  1149. ans.add(temp, BigUnsigned(blk[digitNum]));
  1150. }
  1151. return ans;
  1152. }
  1153. BigUnsignedInABase::BigUnsignedInABase(const std::string &s, Base base) {
  1154. if (base > 36)
  1155. throw "BigUnsignedInABase(std::string, Base): The default string conversion routines use the symbol set 0-9, A-Z and therefore support only up to base 36. You tried a conversion with a base over 36; write your own string conversion routine.";
  1156. this->base = base;
  1157. len = Index(s.length());
  1158. allocate(len);
  1159. Index digitNum, symbolNumInString;
  1160. for (digitNum = 0; digitNum < len; digitNum++) {
  1161. symbolNumInString = len - 1 - digitNum;
  1162. char theSymbol = s[symbolNumInString];
  1163. if (theSymbol >= '0' && theSymbol <= '9')
  1164. blk[digitNum] = theSymbol - '0';
  1165. else if (theSymbol >= 'A' && theSymbol <= 'Z')
  1166. blk[digitNum] = theSymbol - 'A' + 10;
  1167. else if (theSymbol >= 'a' && theSymbol <= 'z')
  1168. blk[digitNum] = theSymbol - 'a' + 10;
  1169. else
  1170. throw "BigUnsignedInABase(std::string, Base): Bad symbol in input. Only 0-9, A-Z, a-z are accepted.";
  1171. if (blk[digitNum] >= base)
  1172. throw "BigUnsignedInABase::BigUnsignedInABase(const Digit *, Index, Base): A digit is too large for the specified base";
  1173. }
  1174. zapLeadingZeros();
  1175. }
  1176. BigUnsignedInABase::operator std::string() const {
  1177. if (base > 36)
  1178. throw "BigUnsignedInABase ==> std::string: The default string conversion routines use the symbol set 0-9, A-Z and therefore support only up to base 36. You tried a conversion with a base over 36; write your own string conversion routine.";
  1179. if (len == 0)
  1180. return std::string("0");
  1181. char *s = new char[len + 1];
  1182. s[len] = '\0';
  1183. Index digitNum, symbolNumInString;
  1184. for (symbolNumInString = 0; symbolNumInString < len; symbolNumInString++) {
  1185. digitNum = len - 1 - symbolNumInString;
  1186. Digit theDigit = blk[digitNum];
  1187. if (theDigit < 10)
  1188. s[symbolNumInString] = char('0' + theDigit);
  1189. else
  1190. s[symbolNumInString] = char('A' + theDigit - 10);
  1191. }
  1192. std::string s2(s);
  1193. delete [] s;
  1194. return s2;
  1195. }
  1196. std::string bigUnsignedToString(const BigUnsigned &x) {
  1197. return std::string(BigUnsignedInABase(x, 10));
  1198. }
  1199. std::string bigIntegerToString(const BigInteger &x) {
  1200. return (x.getSign() == BigInteger::negative)
  1201. ? (std::string("-") + bigUnsignedToString(x.getMagnitude()))
  1202. : (bigUnsignedToString(x.getMagnitude()));
  1203. }
  1204. BigUnsigned stringToBigUnsigned(const std::string &s) {
  1205. return BigUnsigned(BigUnsignedInABase(s, 10));
  1206. }
  1207. BigInteger stringToBigInteger(const std::string &s) {
  1208. return (s[0] == '-') ? BigInteger(stringToBigUnsigned(s.substr(1, s.length() - 1)), BigInteger::negative)
  1209. : (s[0] == '+') ? BigInteger(stringToBigUnsigned(s.substr(1, s.length() - 1)))
  1210. : BigInteger(stringToBigUnsigned(s));
  1211. }
  1212. std::ostream &operator <<(std::ostream &os, const BigUnsigned &x) {
  1213. BigUnsignedInABase::Base base;
  1214. long osFlags = os.flags();
  1215. if (osFlags & os.dec)
  1216. base = 10;
  1217. else if (osFlags & os.hex) {
  1218. base = 16;
  1219. if (osFlags & os.showbase)
  1220. os << "0x";
  1221. } else if (osFlags & os.oct) {
  1222. base = 8;
  1223. if (osFlags & os.showbase)
  1224. os << '0';
  1225. } else
  1226. throw "std::ostream << BigUnsigned: Could not determine the desired base from output-stream flags";
  1227. std::string s = std::string(BigUnsignedInABase(x, base));
  1228. os << s;
  1229. return os;
  1230. }
  1231. std::ostream &operator <<(std::ostream &os, const BigInteger &x) {
  1232. if (x.getSign() == BigInteger::negative) os << '-';
  1233. os << x.getMagnitude();
  1234. return os;
  1235. }
  1236. BigInteger fibo[5010];
  1237. int main()
  1238. {
  1239. int input;
  1240. fibo[0] = 0;
  1241. fibo[1] = 1;
  1242. for(int i=2 ; i<5001 ; ++i)
  1243. fibo[i] = fibo[i-1]+fibo[i-2];
  1244. while(cin>>input) cout<<"The Fibonacci number for "<<input<<" is "<<fibo[input]<<endl;
  1245. return 0;
  1246. }
Success #stdin #stdout 0s 3556KB
stdin
Standard input is empty
stdout
Standard output is empty