Advertisement
dmkozyrev

bignum

Oct 30th, 2017
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.61 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <vector>
  4.  
  5. typedef long long lld;
  6.  
  7. struct Number;
  8.  
  9. std::ostream& operator<<(std::ostream& os, const Number& num);
  10. int compare (const Number& a, const Number& b);
  11. bool operator<(const Number& a, const Number& b);
  12. bool operator>(const Number& a, const Number& b);
  13. bool operator==(const Number& a, const Number& b);
  14. bool operator!=(const Number& a, const Number& b);
  15. bool operator<=(const Number& a, const Number& b);
  16. bool operator>=(const Number& a, const Number& b);
  17.  
  18. struct Number {
  19. static const int POW10 = (int)1e9;
  20. static const int WIDTH = 9;
  21.  
  22. std::vector<int> digits;
  23.  
  24. Number(int num = 0) : digits(1, num) { }
  25.  
  26. Number(const std::vector<int>& digits) : digits(digits) { }
  27.  
  28. Number& operator+=(const Number& other) {
  29. int s1 = (int)this->digits.size();
  30. int s2 = (int)other.digits.size();
  31. int carry = 0;
  32. for (int i = 0; i < s1 || i < s2 || carry > 0; ++i) {
  33. int d1 = i < s1 ? this->digits[i] : 0;
  34. int d2 = i < s2 ? other.digits[i] : 0;
  35. carry += d1 + d2;
  36. int digit = carry % POW10;
  37. carry /= POW10;
  38. if (i < s1) {
  39. this->digits[i] = digit;
  40. } else {
  41. this->digits.push_back(digit);
  42. }
  43. }
  44. return *this;
  45. }
  46.  
  47. Number& operator-=(const Number& other) {
  48. int s1 = (int)this->digits.size();
  49. int s2 = (int)other.digits.size();
  50. int rem = 0;
  51. for (int i = 0; i < s1 || i < s2 || rem; ++i) {
  52. this->digits[i] -= (i < s2 ? other.digits[i] : 0) + rem;
  53. rem = 0;
  54. if (this->digits[i] < 0) {
  55. this->digits[i] += POW10;
  56. ++rem;
  57. }
  58. }
  59.  
  60. while ((int)digits.size() > 1 && digits.back() == 0) {
  61. digits.pop_back();
  62. }
  63.  
  64. return *this;
  65. }
  66.  
  67.  
  68. Number& operator*=(const int num) {
  69. int s = (int)digits.size();
  70. lld carry = 0;
  71. for (int i = 0; i < s || carry; ++i) {
  72. carry += 1LL * num * (i < s ? this->digits[i] : 0);
  73. int digit = carry % POW10;
  74. carry /= POW10;
  75. if (i < s) {
  76. this->digits[i] = digit;
  77. } else {
  78. this->digits.push_back(digit);
  79. }
  80. }
  81.  
  82. while ((int)digits.size() > 1 && digits.back() == 0) {
  83. digits.pop_back();
  84. }
  85.  
  86. return *this;
  87. }
  88.  
  89. Number operator*(const Number& other) const {
  90. int s1 = (int)this->digits.size();
  91. int s2 = (int)other.digits.size();
  92. std::vector<int> answer(s1+s2);
  93. for (int i = 0; i < s1; ++i) {
  94. lld carry = 0;
  95. for (int j = 0; j < s2; ++j) {
  96. carry += answer[i+j] + 1LL * this->digits[i] * other.digits[j];
  97. answer[i+j] = carry % POW10;
  98. carry /= POW10;
  99. }
  100. if (carry > 0) {
  101. answer[i+s2] += carry;
  102. }
  103. }
  104. while ((int)answer.size() > 1 && answer.back() == 0) {
  105. answer.pop_back();
  106. }
  107.  
  108. return Number(answer);
  109. }
  110.  
  111. Number operator/ (const Number& other) {
  112. Number answer = 0, curr = 0;
  113. for (int i = (int)this->digits.size()-1; i >= 0; --i) {
  114. std::cout << "\nbefore shift: " << curr << std::endl;
  115. curr.shift(1); // * POW10
  116. std::cout << "after shift: " << curr << std::endl << std::endl;
  117. curr.digits[0] = this->digits[i];
  118. // подбираем максимальное число x, такое что b * x <= curValue
  119. int x = 0, l = 0, r = POW10;
  120. while (l <= r) {
  121. int m = (l + r) >> 1;
  122. Number temp = other * m;
  123. if (temp <= curr) {
  124. x = m;
  125. l = m+1;
  126. } else {
  127. r = m-1;
  128. }
  129. }
  130. answer.digits[i] = x;
  131. curr -= other * x;
  132. }
  133. // избавляемся от лидирующих нулей
  134. while ((int)answer.digits.size() > 1 && answer.digits.back() == 0) {
  135. answer.digits.pop_back();
  136. }
  137.  
  138. return answer;
  139. }
  140.  
  141. Number& shift(int value) {
  142. if (value > 0) {
  143. for (int i = 0; i < value; ++i) {
  144. digits.push_back(0);
  145. }
  146. for (int i = (int)digits.size()-1; i >= value; --i) {
  147. digits[i] = digits[i-value];
  148. }
  149. for (int i = value-1; i >= 0; --i) {
  150. digits[i] = 0;
  151. }
  152. } else if (value < 0) {
  153. value = -value;
  154. if (value >= (int)digits.size()) {
  155. digits.assign(1, 0);
  156. return *this;
  157. }
  158. for (int i = 0; i <= (int)digits.size()-1-value; ++i) {
  159. digits[i] = digits[i+value];
  160. }
  161. for (int i = 0; i < value; ++i) {
  162. digits.pop_back();
  163. }
  164. }
  165.  
  166. while ((int)digits.size() > 1 && digits.back() == 0) {
  167. digits.pop_back();
  168. }
  169.  
  170. return *this;
  171. }
  172. };
  173.  
  174. std::ostream& operator<<(std::ostream& os, const Number& num) {
  175. os << num.digits.back();
  176. for (int i = (int)num.digits.size()-2; i >= 0; --i) {
  177. os << std::setw(Number::WIDTH) << std::setfill('0') << num.digits[i];
  178. }
  179. return os << std::setfill(' ');
  180. }
  181.  
  182. int compare (const Number& a, const Number& b) {
  183. if (a.digits.size() < b.digits.size()) {
  184. return -1;
  185. }
  186.  
  187. if (a.digits.size() > b.digits.size()) {
  188. return 1;
  189. }
  190.  
  191. for (int i = (int)a.digits.size()-1; i >= 0; --i) {
  192. if (a.digits[i] < b.digits[i]) {
  193. return -1;
  194. } else if (a.digits[i] > b.digits[i]) {
  195. return 1;
  196. }
  197. }
  198. return 0;
  199. }
  200.  
  201. bool operator<(const Number& a, const Number& b) {
  202. return compare(a, b) == -1;
  203. }
  204.  
  205. bool operator>(const Number& a, const Number& b) {
  206. return compare(a, b) == 1;
  207. }
  208.  
  209. bool operator==(const Number& a, const Number& b) {
  210. return compare(a, b) == 0;
  211. }
  212.  
  213. bool operator!=(const Number& a, const Number& b) {
  214. return compare(a, b) != 0;
  215. }
  216.  
  217. bool operator<=(const Number& a, const Number& b) {
  218. return compare(a, b) <= 0;
  219. }
  220.  
  221. bool operator>=(const Number& a, const Number& b) {
  222. return compare(a, b) >= 0;
  223. }
  224.  
  225. int main() {
  226. Number a = 1, b = 1, c = 1;
  227. for (int i = 1; i <= 100; ++i) {
  228. a *= 2;
  229. b *= 3;
  230. c *= 6;
  231. }
  232.  
  233. std::cout << "compare:"<< std::endl;
  234. std::cout << "\t" <<a*b << std::endl;
  235. std::cout << "\t" << c << std::endl;
  236.  
  237. std::cout << "compare:"<< std::endl;
  238. std::cout << "\t" << c / a << std::endl;
  239. std::cout << "\t" << b << std::endl;
  240.  
  241. std::cout << "compare:"<< std::endl;
  242. std::cout << "\t" << c / b << std::endl;
  243. std::cout << "\t" << a << std::endl;
  244.  
  245. return 0;
  246. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement