BigInt64.hpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. #ifndef BIGINT64_HPP
  2. #define BIGINT64_HPP
  3. #include <cstdint>
  4. #include <cstdlib>
  5. #include <cmath>
  6. #include <cassert>
  7. #include <algorithm>
  8. #include <iterator>
  9. #include <limits>
  10. #include <initializer_list>
  11. #include <deque>
  12. #include <vector>
  13. #include <string>
  14. #include <bitset>
  15. #include <iostream>
  16. const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
  17. const __uint128_t _m = ((__uint128_t)1) << 64;
  18. template<typename T>
  19. inline int signum(T t){
  20. if(t < 0)return -1;
  21. if(t >= 0)return 1;
  22. assert(false);
  23. }
  24. inline std::ostream& operator<<(std::ostream& out, __uint128_t o){
  25. if(o == 0)return out << "0";
  26. while(o > 0){
  27. out << std::to_string((int)(o % 10));
  28. o /= 10;
  29. }
  30. return out;
  31. }
  32. struct BigInt{
  33. using size_t = std::size_t;
  34. using ssize_t = std::int64_t;
  35. using uint64_t = std::uint64_t;
  36. using uint32_t = std::uint32_t;
  37. using lui = ::__uint128_t;
  38. using iterator = std::deque<uint64_t>::iterator;
  39. using const_iterator = std::deque<uint64_t>::const_iterator;
  40. using reverse_iterator = std::deque<uint64_t>::reverse_iterator;
  41. using const_reverse_iterator = std::deque<uint64_t>::const_reverse_iterator;
  42. std::deque<uint64_t> data;
  43. int signum;
  44. inline BigInt() : data(1,0),signum(1){}
  45. inline BigInt(size_t _s, uint64_t fill) : data(_s, fill), signum(1){}
  46. inline BigInt(int a) : data(1, std::abs(a)),signum(::signum(a)){}
  47. inline BigInt(unsigned int a) : data(1, a),signum(1){}
  48. inline BigInt(unsigned long long a) : data(1, a), signum(1){}
  49. inline BigInt(long long a) : data(1, std::abs(a)),signum(::signum(a)){}
  50. inline BigInt(const std::initializer_list<uint64_t>& l) : data(l), signum(1){}
  51. inline BigInt(std::initializer_list<uint64_t>&& l) : data(std::move(l)), signum(1){}
  52. inline BigInt(const BigInt& o) : data(o.data), signum(o.signum){}
  53. inline BigInt(BigInt&& o) : data(std::move(o.data)), signum(o.signum){}
  54. inline BigInt(const std::string& o){
  55. auto it = o.rbegin();
  56. BigInt baseTen(1);
  57. while(it != o.rend()){
  58. BigInt l = baseTen.mult(BigInt(*it - '0'));
  59. adda(l);
  60. baseTen = baseTen.mult(BigInt(10));
  61. ++it;
  62. }
  63. }
  64. template<typename InputIterator>
  65. inline BigInt(InputIterator begin, InputIterator end) : data(begin, end), signum(1){}
  66. template<typename RNG>
  67. inline BigInt(RNG& rng, size_t length) : data(length, 0), signum(1){std::generate(data.begin(),data.end(), [&rng](){return rng();});}
  68. inline std::deque<uint64_t>::iterator begin(){return data.begin();}
  69. inline std::deque<uint64_t>::iterator end(){return data.end();}
  70. inline std::deque<uint64_t>::reverse_iterator rbegin(){return data.rbegin();}
  71. inline std::deque<uint64_t>::reverse_iterator rend(){return data.rend();}
  72. inline std::deque<uint64_t>::const_iterator begin()const{return data.begin();}
  73. inline std::deque<uint64_t>::const_iterator end()const{return data.end();}
  74. inline std::deque<uint64_t>::const_reverse_iterator rbegin()const{return data.rbegin();}
  75. inline std::deque<uint64_t>::const_reverse_iterator rend()const{return data.rend();}
  76. inline uint64_t& operator[](size_t i){return data[i];}
  77. inline const uint64_t& operator[](size_t i)const{return data[i];}
  78. inline size_t size()const{return data.size();}
  79. inline auto cbegin()const{return data.cbegin();}
  80. inline auto cend()const{return data.cend();}
  81. inline auto crbegin()const{return data.crbegin();}
  82. inline auto crend()const{return data.crend();}
  83. inline BigInt& operator=(const BigInt& o){signum = o.signum;std::fill(std::copy(o.rbegin(),o.rend(),rbegin()),rend(),0);return *this;}
  84. inline BigInt& operator=(BigInt&& o){data = std::move(o.data);signum = o.signum;return *this;}
  85. inline size_t bitscanForward()const{
  86. auto it = begin();
  87. size_t s = 0;
  88. while(*it == 0 && it != end()){
  89. ++it;
  90. s += 64;
  91. }
  92. if(it == end())return s + 64;
  93. return s + __builtin_clzll(*it);
  94. }
  95. inline size_t bitscanReverse()const{
  96. auto it = rbegin();
  97. size_t s = 0;
  98. while(*it == 0 && it != rend()){
  99. ++it;
  100. s += 64;
  101. }
  102. if(it == rend())return s + 64;
  103. return s + __builtin_ctzll(*it);
  104. }
  105. inline bool operator<(const BigInt& o)const{
  106. if(signum > o.signum){
  107. return false;
  108. }
  109. if(signum < o.signum){
  110. return true;
  111. }
  112. const_iterator it1 = begin();
  113. const_iterator it2 = o.begin();
  114. if(size() > o.size()){
  115. it1 += size() - o.size();
  116. auto _t = begin();
  117. while(_t != it1){
  118. if(*_t)return false;
  119. ++_t;
  120. }
  121. }
  122. else if(size() < o.size()){
  123. it2 += o.size() - size();
  124. auto _t = o.begin();
  125. while(_t != it2){
  126. if(*_t)return true;
  127. ++_t;
  128. }
  129. }
  130. while(it1 != end() && it2 != o.end()){
  131. if(*(it1) < *(it2))return true;
  132. if(*(it1) > *(it2))return false;
  133. ++it1;++it2;
  134. }
  135. return false;
  136. }
  137. inline bool operator>(const BigInt& o)const{
  138. if(signum < o.signum){
  139. return false;
  140. }
  141. if(signum > o.signum){
  142. return true;
  143. }
  144. const_iterator it1 = begin();
  145. const_iterator it2 = o.begin();
  146. if(size() > o.size()){
  147. it1 += size() - o.size();
  148. auto _t = begin();
  149. while(_t != it1){
  150. if(*_t)return true;
  151. ++_t;
  152. }
  153. }
  154. else if(size() < o.size()){
  155. it2 += o.size() - size();
  156. auto _t = o.begin();
  157. while(_t != it2){
  158. if(*_t)return false;
  159. ++_t;
  160. }
  161. }
  162. while(it1 != end() && it2 != o.end()){
  163. if(*(it1) > *(it2))return true;
  164. if(*(it1) < *(it2))return false;
  165. ++it1;++it2;
  166. }
  167. return false;
  168. }
  169. inline bool operator<=(const BigInt& o)const{
  170. if(signum > o.signum){
  171. return false;
  172. }
  173. if(signum < o.signum){
  174. return true;
  175. }
  176. const_iterator it1 = begin();
  177. const_iterator it2 = o.begin();
  178. if(size() > o.size()){
  179. it1 += size() - o.size();
  180. auto _t = begin();
  181. while(_t != it1){
  182. if(*_t)return true;
  183. ++_t;
  184. }
  185. }
  186. else if(size() < o.size()){
  187. it2 += o.size() - size();
  188. auto _t = o.begin();
  189. while(_t != it2){
  190. if(*_t)return false;
  191. ++_t;
  192. }
  193. }
  194. while(it1 != end() && it2 != o.end()){
  195. if(*(it1) < *(it2))return true;
  196. if(*(it1) > *(it2))return false;
  197. ++it1;++it2;
  198. }
  199. return true;
  200. }
  201. inline bool operator>=(const BigInt& o)const{
  202. if(signum < o.signum){
  203. return false;
  204. }
  205. if(signum > o.signum){
  206. return true;
  207. }
  208. const_iterator it1 = begin();
  209. const_iterator it2 = o.begin();
  210. if(size() > o.size()){
  211. it1 += size() - o.size();
  212. auto _t = begin();
  213. while(_t != it1){
  214. if(*_t)return true;
  215. ++_t;
  216. }
  217. }
  218. else if(size() < o.size()){
  219. it2 += o.size() - size();
  220. auto _t = o.begin();
  221. while(_t != it2){
  222. if(*_t)return false;
  223. ++_t;
  224. }
  225. }
  226. while(it1 != end() && it2 != o.end()){
  227. if(*(it1) > *(it2))return true;
  228. if(*(it1) < *(it2))return false;
  229. ++it1;++it2;
  230. }
  231. return true;
  232. }
  233. inline bool operator==(const BigInt& o)const{
  234. if(signum < o.signum){
  235. return false;
  236. }
  237. if(signum > o.signum){
  238. return false;
  239. }
  240. const_iterator it1 = begin();
  241. const_iterator it2 = o.begin();
  242. if(size() > o.size()){
  243. it1 += size() - o.size();
  244. auto _t = begin();
  245. while(_t != it1){
  246. if(*_t)return false;
  247. ++_t;
  248. }
  249. }
  250. else if(size() < o.size()){
  251. it2 += o.size() - size();
  252. auto _t = o.begin();
  253. while(_t != it2){
  254. if(*_t)return false;
  255. ++_t;
  256. }
  257. }
  258. while(it1 != end() && it2 != o.end()){
  259. if(*(it1) != *(it2))return false;
  260. ++it1;++it2;
  261. }
  262. return true;
  263. }
  264. inline bool operator==(uint64_t o){
  265. return size() == 1 && *rbegin() == o;
  266. }
  267. inline bool isZero()const{
  268. for(auto it = data.begin();it != data.end();it++){
  269. if(*it)return false;
  270. }
  271. return true;
  272. }
  273. inline void setZero(){
  274. for(auto it = begin();it != end();it++)*it = 0;
  275. }
  276. inline BigInt& trim(){
  277. while(data[0] == 0 && data.size() > 1){
  278. data.pop_front();
  279. }
  280. return *this;
  281. }
  282. inline BigInt div(uint64_t d)const{
  283. BigInt ret = *this;
  284. lui carry = 0;
  285. for(auto it = ret.data.begin();it != ret.data.end();it++){
  286. lui temp = (lui)*it;
  287. temp += carry;
  288. carry = temp % d;
  289. *it = (uint64_t)(temp / d);
  290. carry <<= 64;
  291. }
  292. return ret;
  293. }
  294. inline BigInt& div(uint64_t d){
  295. lui carry = 0;
  296. for(auto it = data.begin();it != data.end();it++){
  297. lui temp = (lui)*it;
  298. temp += carry;
  299. carry = temp % d;
  300. *it = (uint64_t)(temp / d);
  301. carry <<= 64;
  302. }
  303. return *this;
  304. }
  305. inline uint64_t mod(uint64_t m)const{
  306. lui carry = 0;
  307. for(auto it = data.begin();it != data.end();it++){
  308. carry <<= 64;
  309. carry = (*it + carry) % m;
  310. }
  311. return carry;
  312. }
  313. inline BigInt& bitshiftLeft(int c){
  314. if(c < 0)return bitshiftRight(-c);
  315. unsigned int sh = c % 64;
  316. unsigned int jmp = c / 64;
  317. if((unsigned int)jmp >= size()){std::fill(begin(),end(),0);return *this;}
  318. auto it1 = begin();
  319. auto it2 = it1 + jmp;
  320. auto beforeEnd = end() - 1;
  321. while(it2 != beforeEnd){
  322. *it1 = (*it2 << sh);
  323. if(sh)
  324. *it1 |= (*(it2 + 1) >> (64 - sh));
  325. ++it1;++it2;
  326. }
  327. *it1 = (*it2 << sh);
  328. ++it1;++it2;
  329. while(it1 != end()){
  330. *it1 = 0;
  331. ++it1;
  332. }
  333. return *this;
  334. }
  335. inline BigInt& bitshiftLeft_expand(int c){
  336. if(c < 0)return bitshiftRight(-c);
  337. unsigned int sh = c % 64;
  338. unsigned int jmp = c / 64;
  339. int insert_count = std::max((size_t)0, jmp - bitscanForward() / 64 + 1);
  340. while(insert_count --> 0)
  341. data.push_front(0);
  342. auto it1 = begin();
  343. auto it2 = it1 + jmp;
  344. auto beforeEnd = end() - 1;
  345. while(it2 != beforeEnd){
  346. *it1 = (*it2 << sh);
  347. if(sh)
  348. *it1 |= (*(it2 + 1) >> (64 - sh));
  349. ++it1;++it2;
  350. }
  351. *it1 = (*it2 << sh);
  352. ++it1;++it2;
  353. while(it1 != end()){
  354. *it1 = 0;
  355. ++it1;
  356. }
  357. return *this;
  358. }
  359. inline BigInt& bitshiftRight(int c){
  360. if(c < 0)return bitshiftLeft(-c);
  361. unsigned int sh = c % 64;
  362. unsigned int jmp = c / 64;
  363. if((unsigned int)jmp >= size()){std::fill(begin(),end(),0);return *this;}
  364. auto it1 = rbegin();
  365. auto it2 = it1 + jmp;
  366. auto beforeRend = rend() - 1;
  367. while(it2 != beforeRend){
  368. *it1 = (*it2 >> sh);
  369. if(sh)
  370. *it1 |= (*(it2 + 1) << (64 - sh));
  371. ++it1;++it2;
  372. }
  373. *it1 = (*it2 >> sh);
  374. ++it1;++it2;
  375. while(it1 != rend()){
  376. *it1 = 0;
  377. ++it1;
  378. }
  379. return *this;
  380. }
  381. inline BigInt operator<<(int c)const{
  382. BigInt ret = *this;
  383. ret.bitshiftLeft(c);
  384. return ret;
  385. }
  386. inline BigInt operator>>(int c)const{
  387. BigInt ret = *this;
  388. ret.bitshiftRight(c);
  389. return ret;
  390. }
  391. inline BigInt& operator<<=(int c){
  392. return bitshiftLeft(c);
  393. }
  394. inline BigInt& operator>>=(int c){
  395. return bitshiftRight(c);
  396. }
  397. inline BigInt& operator&=(const BigInt& o){
  398. auto it1 = rbegin();
  399. auto it2 = o.rbegin();
  400. while(it1 != rend() && it2 != o.rend())
  401. *(it1++) &= *(it2++);
  402. return *this;
  403. }
  404. inline BigInt& operator|=(const BigInt& o){
  405. auto it1 = rbegin();
  406. auto it2 = o.rbegin();
  407. while(it1 != rend() && it2 != o.rend())
  408. *(it1++) |= *(it2++);
  409. return *this;
  410. }
  411. inline BigInt& operator^=(const BigInt& o){
  412. auto it1 = rbegin();
  413. auto it2 = o.rbegin();
  414. while(it1 != rend() && it2 != o.rend())
  415. *(it1++) ^= *(it2++);
  416. return *this;
  417. }
  418. inline BigInt operator&(const BigInt& o)const{
  419. BigInt ret(*this);
  420. ret &= o;
  421. return ret;
  422. }
  423. inline BigInt operator|(const BigInt& o)const{
  424. BigInt ret(*this);
  425. ret |= o;
  426. return ret;
  427. }
  428. inline BigInt operator^(const BigInt& o)const{
  429. BigInt ret(*this);
  430. ret ^= o;
  431. return ret;
  432. }
  433. inline int bitDifference(const BigInt& o){
  434. int pos1(0),pos2(0);
  435. auto it1 = begin();
  436. auto it2 = o.begin();
  437. bool bitfound = false;
  438. while(it1 != end()){
  439. if(*it1 == 0)
  440. pos1 += 64;
  441. else{
  442. pos1 += __builtin_clzll(*it1);
  443. bitfound = true;
  444. break;
  445. }
  446. ++it1;
  447. }
  448. if(!bitfound)pos1 = size() * 64;
  449. bitfound = false;
  450. while(it2 != o.end()){
  451. if(*it2 == 0)
  452. pos2 += 64;
  453. else{
  454. pos2 += __builtin_clzll(*it2);
  455. bitfound = true;
  456. break;
  457. }
  458. ++it2;
  459. }
  460. if(!bitfound)pos2 = o.size() * 64;
  461. int sizediff = ((signed int)size()) - ((signed int)o.size());
  462. return pos2 - pos1 + sizediff * 64;
  463. }
  464. inline BigInt& chunkshiftLeft(int c){
  465. if(c < 0)return chunkshiftRight(-c);
  466. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  467. auto it1 = data.begin();
  468. auto it2 = it1 + c;
  469. while(it2 != data.end())*(it1++) = *(it2++);
  470. while(it1 != data.end())*(it1++) = 0;
  471. return *this;
  472. }
  473. inline BigInt& chunkshiftRight(int c){
  474. if(c < 0)return chunkshiftLeft(-c);
  475. if((unsigned int)c >= size()){std::fill(begin(),end(),0);return *this;}
  476. auto it1 = data.rbegin();
  477. auto it2 = it1 + c;
  478. while(it2 != data.rend())*(it1++) = *(it2++);
  479. while(it1 != data.rend())*(it1++) = 0;
  480. return *this;
  481. }
  482. inline BigInt bitshiftLeft(int c)const{
  483. if(c < 0)return bitshiftRight(-c);
  484. BigInt _this = *this;
  485. _this.bitshiftLeft(c);
  486. return _this;
  487. }
  488. inline BigInt bitshiftRight(int c)const{
  489. if(c < 0)return bitshiftLeft(-c);
  490. BigInt _this = *this;
  491. _this.bitshiftRight(c);
  492. return _this;
  493. }
  494. inline BigInt chunkshiftLeft(int c)const{
  495. if(c < 0)return chunkshiftRight(-c);
  496. BigInt _this = *this;
  497. _this.chunkshiftLeft(c);
  498. return _this;
  499. }
  500. inline BigInt chunkshiftRight(int c)const{
  501. if(c < 0)return chunkshiftLeft(-c);
  502. BigInt _this = *this;
  503. _this.chunkshiftRight(c);
  504. return _this;
  505. }
  506. inline BigInt add(const BigInt& o){
  507. BigInt ret = *this;
  508. ret.adda(o);
  509. return ret;
  510. }
  511. inline BigInt& adda(const BigInt& o){
  512. while(size() < o.size())data.push_front(0);
  513. bool carry = 0;
  514. auto it1 = rbegin();
  515. auto it2 = o.rbegin();
  516. while(it1 != rend() && it2 != o.rend()){
  517. carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
  518. carry |= (*it2 + carry) == 0 && *it2;
  519. it1++;
  520. it2++;
  521. }
  522. while(it1 != rend() && carry){
  523. carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  524. ++it1;
  525. }
  526. if(carry)data.push_front(1);
  527. return *this;
  528. }
  529. inline BigInt& suba(const BigInt& o){
  530. assert((*this) >= (o));
  531. bool carry = 0;
  532. auto it1 = rbegin();
  533. auto it2 = o.rbegin();
  534. while(it1 != rend() && it2 != o.rend()){
  535. carry = __builtin_usubll_overflow(*it1 - carry, *it2, (unsigned long long*)(&(*it1)));
  536. if(!carry)carry = ((*it1 - carry) == std::numeric_limits<uint64_t>::max());
  537. ++it1;++it2;
  538. }
  539. while(it1 != rend() && carry){
  540. carry = __builtin_usubll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
  541. ++it1;
  542. }
  543. return *this;
  544. }
  545. inline BigInt& moda(const BigInt& o){
  546. assert(!o.isZero());
  547. if(o > *this)return *this;
  548. BigInt mo = o;
  549. mo = o;
  550. int bd = bitDifference(o);
  551. mo.bitshiftLeft_expand(bd);
  552. if(mo > *this)mo.bitshiftRight(1);
  553. this->suba(mo);
  554. if(*this < o)return *this;
  555. while(true){
  556. bd = mo.bitDifference(*this);
  557. mo >>= bd;
  558. mo.trim();
  559. if(mo > *this)mo >>= 1;
  560. this->suba(mo);
  561. if(*this < o)return *this;
  562. }
  563. return *this;
  564. }
  565. inline bool even(){
  566. return !(*rbegin() & 1);
  567. }
  568. inline BigInt modPow(BigInt o, const BigInt& mod)const{
  569. BigInt t = *this;
  570. BigInt odd(1);
  571. while(true){
  572. if(o.even()){
  573. t = t.mult(t);
  574. t.trim();
  575. t.moda(mod);
  576. o.div(2);
  577. }
  578. else{
  579. odd = odd.mult(t);
  580. odd.moda(mod);
  581. odd.trim();
  582. t.trim();
  583. t.moda(mod);
  584. o.suba(BigInt(1));
  585. }
  586. std::cout << "Reduced" << std::endl;
  587. o.trim();
  588. if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
  589. }
  590. }
  591. inline BigInt mult(const BigInt& o)const{
  592. BigInt result(size() + o.size() + 1,0);
  593. BigInt temp(size() + o.size() + 1,0);
  594. int p = 0;
  595. for(auto it1 = rbegin();it1 != rend();it1++){
  596. auto it = temp.rbegin();
  597. lui carry = 0;
  598. for(auto it2 = o.rbegin();it2 != o.rend();it2++){
  599. lui prod = ((lui)*it1) * (*it2);
  600. prod += carry;
  601. *(it++) = (uint64_t)prod;
  602. carry = (prod >> 64);
  603. }
  604. if(carry)(*it) += carry;
  605. temp.chunkshiftLeft(p++);
  606. result.adda(temp);
  607. temp.setZero();
  608. }
  609. result.trim();
  610. return result;
  611. }
  612. inline std::string rawString()const{
  613. std::string s = "";
  614. bool flag;
  615. for(unsigned int i = 0;i < size();i++){
  616. if(data[i])flag = true;
  617. if(flag);
  618. s += std::to_string(data[i]);
  619. if(i < size() - 1)s += "|";
  620. }
  621. return s;
  622. }
  623. inline std::string bitString()const{
  624. auto it = begin();
  625. std::string ret = "";
  626. //std::cout << size() << "; " << std::flush;
  627. while(it != end()){
  628. std::bitset<64> bits(*it);
  629. for(unsigned int i = 0;i < 64;i++){
  630. ret += chars.at(((*it) & (1ULL << (64 - i))) != 0);
  631. }
  632. ++it;
  633. }
  634. return ret;
  635. }
  636. inline std::string toString()const{
  637. if(isZero())return std::to_string(0);
  638. std::deque<char> c_str;
  639. const uint64_t q = 1000000000000000000ULL;
  640. BigInt diver = *this;
  641. while(!diver.isZero()){
  642. std::string frac = std::to_string(diver.mod(q));
  643. int a = 0;
  644. for(auto it = frac.rbegin();it != frac.rend();it++){
  645. c_str.push_front(*it);
  646. a++;
  647. }
  648. while(a < 18){
  649. c_str.push_front('0');
  650. a++;
  651. }
  652. diver.div(q);
  653. }
  654. auto it = c_str.begin();
  655. while(*(it) == '0')++it;
  656. return std::string(it, c_str.end());
  657. }
  658. inline std::string toString(unsigned int base)const{
  659. if(isZero())return std::to_string(0);
  660. if(base == 2)return bitString();
  661. if(base == 10)return toString();
  662. std::vector<char> c_str;
  663. c_str.reserve(size() * (unsigned int)(64.0 * std::log(2) / std::log((double)base)));
  664. BigInt diver = *this;
  665. while(!diver.isZero()){
  666. c_str.push_back(chars.at(diver.mod(base)));
  667. diver.div(base);
  668. }
  669. return std::string(c_str.rbegin(), c_str.rend());
  670. }
  671. };
  672. namespace std{
  673. template<>
  674. struct hash<BigInt>{
  675. inline size_t operator()(const BigInt& o)const{
  676. size_t ret = 0;
  677. std::for_each(o.begin(), o.end(), [&ret](const uint64_t& ui){ret ^= ui;});
  678. return ret;
  679. }
  680. };
  681. }
  682. #endif //BIGINT64_HPP