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