BigInt.hpp 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. #ifndef BIGINT_HPP
  2. #define BIGINT_HPP
  3. #include <cstdint>
  4. #include <deque>
  5. #include <string>
  6. #include <cmath>
  7. #include <bitset>
  8. using std::size_t;
  9. inline std::uint32_t u(uint64_t a){
  10. return (uint32_t)(a >> 32);
  11. }
  12. inline std::uint32_t l(uint64_t a){
  13. return (uint32_t)(a & 0x00000000FFFFFFFF);
  14. }
  15. template<typename T>
  16. inline int signum(T t){
  17. if(t > 0)return 1;
  18. if(t < 0)return -1;
  19. return 0;
  20. }
  21. struct BigInt{
  22. using uint64_t = std::uint64_t;
  23. using uint32_t = std::uint32_t;
  24. int signum;
  25. std::deque<std::uint64_t> data;
  26. inline BigInt(size_t size, bool dummy) : data(size, 0){
  27. }
  28. inline BigInt(unsigned int n) : data(1, 0){
  29. data[0] = n;
  30. }
  31. inline BigInt(unsigned long long n) : data(2, 0){
  32. data[1] = l(n);
  33. data[0] = u(n);
  34. }
  35. inline BigInt(unsigned long long n, size_t _size) : data(_size, 0){
  36. data[_size - 1] = l(n);
  37. data[_size - 2] = u(n);
  38. }
  39. inline BigInt(int n) : data(1, 0){
  40. data[0] = std::abs(n);
  41. signum = ::signum(n);
  42. }
  43. inline BigInt(long long n) : data(2, 0){
  44. data[1] = l(std::abs(n));
  45. data[0] = u(std::abs(n));
  46. signum = ::signum(n);
  47. }
  48. inline uint64_t mod(uint64_t o){
  49. uint64_t carry = 0;
  50. for(size_t i = 0;i < data.size();i++){
  51. carry = ((carry << 32) + data[i]) % o;
  52. }
  53. return carry;
  54. }
  55. inline BigInt div(uint32_t o){
  56. uint64_t carry = 0;
  57. BigInt ret = *this;
  58. for(size_t i = 0;i < data.size();i++){
  59. ret.data[i] = (data[i] + (carry << 32)) / o;
  60. carry = (data[i] + (carry << 32)) % o;
  61. }
  62. return ret;
  63. }
  64. inline BigInt add(const BigInt& other){
  65. BigInt ret((size_t)std::max((size_t)data.size(), (size_t)other.data.size()), false);
  66. uint64_t carry = 0;
  67. for(size_t s = 0;s < std::max(data.size(), other.data.size());s++){
  68. uint64_t s1 = (s >= data.size() ? 0 : data[data.size() - s - 1]);
  69. uint64_t s2 = (s >= other.size() ? 0 : other.data[other.size() - s - 1]);
  70. uint64_t sum = s1 + s2 + carry;
  71. ret.data[ret.size() - s - 1] = l(sum);
  72. carry = u(sum);
  73. }
  74. return ret;
  75. }
  76. void trim(){
  77. while(!(data[1] | data[0]))data.pop_front();
  78. }
  79. inline BigInt mult(const BigInt& other){
  80. std::deque<std::deque<uint64_t>> matrix(size(), std::deque<uint64_t>(other.size() + 1, 0));
  81. uint64_t carry = 0;
  82. BigInt ret(size() + other.size(), false);
  83. for(size_t i = 0;i < size();i++){
  84. carry = 0;
  85. for(size_t ih = 0;ih < other.size();ih++){
  86. uint64_t res = data[size() - i - 1] * other.data[other.size() - ih - 1];
  87. res += carry;
  88. matrix[i][ih] = l(res);
  89. carry = u(res);
  90. }
  91. }
  92. carry = 0;
  93. if(false)
  94. for(size_t i = 0;i < matrix.size();i++){
  95. for(size_t ih = 0;ih < matrix.size();ih++){
  96. std::cout << matrix[i][ih] << " ";
  97. }
  98. std::cout << std::endl;
  99. }
  100. for(size_t column = 0;column < (matrix.size() + other.size());column++){
  101. uint64_t accum = 0;
  102. for(size_t row = 0;row < matrix.size();row++){
  103. if(row > column)goto end;
  104. else if(column - row < matrix[row].size()){
  105. accum += matrix[row][column - row];
  106. }
  107. }
  108. end:
  109. accum += carry;
  110. carry = u(accum);
  111. ret.data[ret.size() - column - 1] = l(accum);
  112. }
  113. ret.trim();
  114. return ret;
  115. }
  116. inline BigInt& bitshiftLeft(int c){
  117. if(c < 0)return bitshiftRight(-c);
  118. int jump = c / 32;
  119. int sh = c % 32;
  120. for(int i = 0;i < (int)(size()) - jump;i++){
  121. data[i] = l(data[i + jump] << sh);
  122. if(i < size() - jump - 1){
  123. data[i] |= data[i + jump + 1] >> (32 - sh);
  124. }
  125. }
  126. for(int i = std::max(0,(int)(size()) - jump);i < size();i++){
  127. data[i] = 0;
  128. }
  129. return *this;
  130. }
  131. inline BigInt& bitshiftRight(int c){
  132. if(c < 0)return bitshiftLeft(-c);
  133. unsigned int jump = c / 32;
  134. unsigned int sh = c % 32;
  135. for(unsigned int i = size() - 1;i >= jump;i--){
  136. data[i] = data[i - jump] >> sh;
  137. if(i > jump){
  138. data[i] |= l(data[i - jump - 1] << (32 - sh));
  139. }
  140. }
  141. for(int i = jump - 1;i >= 0;i--){
  142. data[i] = 0;
  143. }
  144. return *this;
  145. }
  146. inline BigInt& chunkshiftLeft(int c){
  147. if(c < 0)return chunkshiftRight(-c);
  148. for(int i = 0;i < (int)(size()) - c;i++){
  149. data[i] = data[i + c];
  150. }
  151. for(int i = std::max(0,(int)(size()) - c);i < size();i++){
  152. data[i] = 0;
  153. }
  154. return *this;
  155. }
  156. inline BigInt& chunkshiftRight(int c){
  157. if(c < 0)return chunkshiftLeft(-c);
  158. for(int i = size() - 1;i >= c;i--){
  159. data[i] = data[i - c];
  160. }
  161. for(int i = c - 1;i >= 0;i--){
  162. data[i] = 0;
  163. }
  164. return *this;
  165. }
  166. inline size_t size()const{
  167. return data.size();
  168. }
  169. inline bool operator==(const BigInt& o)const{
  170. auto it1 = data.rbegin();
  171. auto it2 = o.data.rbegin();
  172. while(true){
  173. if(*(it1++) != *(it2++))return false;
  174. if(it1 == data.rend())return true;
  175. if(it2 == o.data.rend())return true;
  176. }
  177. }
  178. inline bool isZero(){
  179. for(uint64_t d : data){
  180. if(d)return false;
  181. }
  182. return true;
  183. }
  184. inline std::string bitString(){
  185. std::vector<char> _bits;
  186. _bits.reserve(data.size() * 32);
  187. for(uint64_t i : data){
  188. std::bitset<64> bits(i);
  189. for(int ih = 0;ih < 32;ih++)
  190. _bits.push_back((bits[32 - ih - 1] == 1) ? '1' : '0');
  191. }
  192. return std::string(_bits.begin(), _bits.end());
  193. }
  194. inline std::string rawString(){
  195. std::string a = "";
  196. for(uint64_t d : data){
  197. a += (std::to_string(d) + "|");
  198. }
  199. return a;
  200. }
  201. inline std::string toString(){
  202. std::string a = "";
  203. BigInt dec(*this);
  204. while(!dec.isZero()){
  205. a = std::to_string(dec.mod(10)) + a;
  206. dec = dec.div(10);
  207. }
  208. return a;
  209. }
  210. };
  211. #endif //BIGINT_HPP