BigInt.hpp 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. #ifndef BIGINT_HPP
  2. #define BIGINT_HPP
  3. #include <cstdint>
  4. #include <deque>
  5. #include <string>
  6. #include <cmath>
  7. using std::size_t;
  8. inline std::uint32_t u(uint64_t a){
  9. return (uint32_t)(a >> 32);
  10. }
  11. inline std::uint32_t l(uint64_t a){
  12. return (uint32_t)(a & 0x00000000FFFFFFFF);
  13. }
  14. template<typename T>
  15. inline int signum(T t){
  16. if(t > 0)return 1;
  17. if(t < 0)return -1;
  18. return 0;
  19. }
  20. struct BigInt{
  21. using uint64_t = std::uint64_t;
  22. using uint32_t = std::uint32_t;
  23. int signum;
  24. std::deque<std::uint64_t> data;
  25. inline BigInt(size_t size, bool dummy) : data(size, 0){
  26. }
  27. inline BigInt(unsigned int n) : data(1, 0){
  28. data[0] = n;
  29. }
  30. inline BigInt(unsigned long long n) : data(2, 0){
  31. data[1] = l(n);
  32. data[0] = u(n);
  33. }
  34. inline BigInt(int n) : data(1, 0){
  35. data[0] = std::abs(n);
  36. signum = ::signum(n);
  37. }
  38. inline BigInt(long long n) : data(2, 0){
  39. data[1] = l(std::abs(n));
  40. data[0] = u(std::abs(n));
  41. signum = ::signum(n);
  42. }
  43. inline uint64_t mod(uint64_t o){
  44. uint64_t carry = 0;
  45. for(size_t i = 0;i < data.size();i++){
  46. carry = ((carry << 32) + data[i]) % o;
  47. }
  48. return carry;
  49. }
  50. inline BigInt div(uint32_t o){
  51. uint64_t carry = 0;
  52. BigInt ret = *this;
  53. for(size_t i = 0;i < data.size();i++){
  54. ret.data[i] = (data[i] + (carry << 32)) / o;
  55. carry = (data[i] + (carry << 32)) % o;
  56. }
  57. return ret;
  58. }
  59. inline BigInt add(const BigInt& other){
  60. BigInt ret((size_t)std::max((size_t)data.size(), (size_t)other.data.size()), false);
  61. uint64_t carry = 0;
  62. for(size_t s = 0;s < std::max(data.size(), other.data.size());s++){
  63. uint64_t s1 = (s >= data.size() ? 0 : data[data.size() - s - 1]);
  64. uint64_t s2 = (s >= other.size() ? 0 : other.data[other.size() - s - 1]);
  65. uint64_t sum = s1 + s2 + carry;
  66. ret.data[ret.size() - s - 1] = l(sum);
  67. carry = u(sum);
  68. }
  69. return ret;
  70. }
  71. void trim(){
  72. while(!(data[1] | data[0]))data.pop_front();
  73. }
  74. inline BigInt mult(const BigInt& other){
  75. std::deque<std::deque<uint64_t>> matrix(size(), std::deque<uint64_t>(other.size() + 1, 0));
  76. uint64_t carry = 0;
  77. BigInt ret(size() + other.size(), false);
  78. for(size_t i = 0;i < size();i++){
  79. carry = 0;
  80. for(size_t ih = 0;ih < other.size();ih++){
  81. uint64_t res = data[size() - i - 1] * other.data[other.size() - ih - 1];
  82. res += carry;
  83. matrix[i][ih] = l(res);
  84. carry = u(res);
  85. }
  86. }
  87. carry = 0;
  88. if(false)
  89. for(size_t i = 0;i < matrix.size();i++){
  90. for(size_t ih = 0;ih < matrix.size();ih++){
  91. std::cout << matrix[i][ih] << " ";
  92. }
  93. std::cout << std::endl;
  94. }
  95. for(size_t column = 0;column < (matrix.size() + other.size());column++){
  96. uint64_t accum = 0;
  97. for(size_t row = 0;row < matrix.size();row++){
  98. if(row > column)goto end;
  99. else if(column - row < matrix[row].size()){
  100. accum += matrix[row][column - row];
  101. }
  102. }
  103. end:
  104. accum += carry;
  105. carry = u(accum);
  106. ret.data[ret.size() - column - 1] = l(accum);
  107. }
  108. ret.trim();
  109. //if(ret.data[0] == 0)ret.data.pop_front();
  110. return ret;
  111. }
  112. inline size_t size()const{
  113. return data.size();
  114. }
  115. inline bool isZero(){
  116. for(uint64_t d : data){
  117. if(d)return false;
  118. }
  119. return true;
  120. }
  121. inline std::string rawString(){
  122. std::string a = "";
  123. for(uint64_t d : data){
  124. a += (std::to_string(d) + "|");
  125. }
  126. return a;
  127. }
  128. inline std::string toString(){
  129. std::string a = "";
  130. BigInt dec(*this);
  131. while(!dec.isZero()){
  132. a = std::to_string(dec.mod(10)) + a;
  133. dec = dec.div(10);
  134. }
  135. return a;
  136. }
  137. };
  138. #endif