deushiro

cpp

Oct 30th, 2020
169
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.74 KB | None | 0 0
  1. #include <iostream>
  2. #include "biginteger.h"
  3.  
  4.  
  5. BigInteger::BigInteger(std::string s) {
  6.   length = s.size();
  7.   for (int digit = 0; digit < length; digit++) {
  8.     number.push_back(s[length - digit - 1] - '0');
  9.   }
  10. }
  11. BigInteger::BigInteger(){
  12.   this->positive = true;
  13.   this->length = 1;
  14.   std::vector<int> num(1,0);
  15.   this->number = num;
  16. }
  17. BigInteger::BigInteger(std::vector<int> &a, bool sign){
  18.   for(int digit = 0; digit < (int)a.size(); ++digit){
  19.     this->number.push_back(a[digit]);
  20.   }
  21.   this->length = (int)a.size();
  22.   this->positive = sign;
  23. };
  24. BigInteger::BigInteger(int x) {
  25.   if(x < 0){
  26.     positive = false;
  27.     x = -x;
  28.   }
  29.   else{
  30.     positive = true;
  31.   }
  32.   if(x == 0){
  33.     number.push_back(0);
  34.     positive = true;
  35.   }
  36.   while(x > 0){
  37.     number.push_back(x % 10);
  38.     x /= 10;
  39.   }
  40.   length = number.size();
  41. }
  42.  
  43. std::string BigInteger::toString(){
  44.   std::string str;
  45.   if(!(this->positive)){
  46.     str.push_back('-');
  47.   }
  48.   for(int digit = this->length - 1; digit >= 0; digit--){
  49.     str.push_back((char)(this->number[digit] + '0'));
  50.   }
  51.   return str;
  52. }
  53. BigInteger BigInteger::operator-(){
  54.   this->positive = !this->positive;
  55.   return *this;
  56. }
  57. BigInteger& BigInteger::operator++()
  58. {
  59.   BigInteger tmp = 1;
  60.   *this += tmp;
  61.   return *this;
  62. }
  63. BigInteger& BigInteger::operator--()
  64. {
  65.   BigInteger tmp = 1;
  66.   *this -= tmp;
  67.   return *this;
  68. }
  69. BigInteger BigInteger::operator++(int)
  70. {
  71.   BigInteger temp = *this;
  72.   ++(*this);
  73.   return temp;
  74. }
  75. BigInteger BigInteger::operator--(int)
  76. {
  77.   BigInteger temp = *this;
  78.   --(*this);
  79.   return temp;
  80. }
  81.  
  82. std::ostream& operator<<(std::ostream &os, const BigInteger& num) {
  83.   if(!num.positive){
  84.     os << "-";
  85.   }
  86.   for(int digit = 0; digit < num.length; ++digit){
  87.     os << num.number[num.length - digit - 1];
  88.   }
  89.   return os;
  90. }
  91. std::istream& operator>>(std::istream &is, BigInteger& num) {
  92.   std::string str;
  93.   is >> str;
  94.   num.number.clear();
  95.   if(str[0] == '-'){
  96.     num.positive = false;
  97.     num.length = (int)str.size() - 1;
  98.     for(int digit = 0; digit < num.length; digit++){
  99.       num.number.push_back(str[num.length - digit] - '0');
  100.     }
  101.   }
  102.   else{
  103.     num.positive = true;
  104.     num.length = (int)str.size();
  105.     for(int digit = 0; digit < num.length; digit++){
  106.       num.number.push_back(str[num.length - digit - 1] - '0');
  107.     }
  108.   }
  109.   return is;
  110. }
  111.  
  112. bool operator== (const BigInteger& left, const BigInteger& right){
  113.   if(left.positive == right.positive && left.length == right.length){
  114.     for(int digit = 0; digit < left.length; ++digit){
  115.       if(left.number[digit] != right.number[digit])
  116.         return false;
  117.     }
  118.   }
  119.   else{
  120.     return false;
  121.   }
  122.   return true;
  123. }
  124. bool operator!= (const BigInteger& left, const BigInteger& right){
  125.   return (!(left == right));
  126. }
  127. bool operator> (const BigInteger& left, const BigInteger& right){
  128.   if(left == right)
  129.     return false;
  130.   if(left.positive && !right.positive)
  131.     return true;
  132.   if(!left.positive && right.positive)
  133.     return false;
  134.   if(left.positive && right.positive){
  135.     if(left.number.size() > right.number.size())
  136.       return true;
  137.     if(left.number.size() < right.number.size())
  138.       return false;
  139.     for(int digit = (int)left.number.size() - 1; digit >= 0; digit--){
  140.       if(left.number[digit] > right.number[digit])
  141.         return true;
  142.       if(left.number[digit] < right.number[digit])
  143.         return false;
  144.     }
  145.   }
  146.   if(left.number.size() < right.number.size())
  147.     return true;
  148.   if(left.number.size() > right.number.size())
  149.     return false;
  150.   for(int digit = (int)left.number.size() - 1; digit >= 0; digit--) {
  151.     if (left.number[digit] < right.number[digit])
  152.       return true;
  153.     if (left.number[digit] > right.number[digit])
  154.       return false;
  155.   }
  156.   return false;
  157.  
  158.  
  159. }
  160. bool operator< (const BigInteger& left, const BigInteger& right){
  161.   return(!(left > right || left == right));
  162. }
  163.  
  164. bool operator<= (const BigInteger& left, const BigInteger& right){
  165.   return ((left < right) || (left == right));
  166. }
  167. bool operator>= (const BigInteger& left, const BigInteger& right){
  168.   return ((left > right) || (left == right));
  169. }
  170.  
  171. BigInteger::operator bool(){
  172.   if(this->length == 1 && this->number[0] == 0){
  173.     return false;
  174.   }
  175.   else
  176.     return true;
  177. }
  178.  
  179. BigInteger operator+(const BigInteger& l, const BigInteger& r) {
  180.   BigInteger left = l;
  181.   BigInteger right = r;
  182.   if(!left.positive){
  183.     if(!right.positive)
  184.       return -(-left + (-right));
  185.     else
  186.       return right - (-left);
  187.   }
  188.   else if (!right.positive)
  189.     return left - (-right);
  190.   int carry = 0;
  191.   for(int digit = 0; digit < std::max(left.length, right.length) || carry != 0; digit++){
  192.     if(digit == left.length) {
  193.       left.number.push_back(0);
  194.       left.length++;
  195.     }
  196.     left.number[digit] += carry + (digit < right.length ? right.number[digit] : 0);
  197.     if(left.number[digit] >= 10){
  198.       carry = 1;
  199.     }
  200.     else
  201.       carry = 0;
  202.     if(carry == 1){
  203.       left.number[digit] -= 10;
  204.     }
  205.   }
  206.   return left;
  207. }
  208. BigInteger operator-(const BigInteger& l, const BigInteger& r){
  209.   BigInteger left = l;
  210.   BigInteger right = r;
  211.   if(!right.positive)
  212.     return left + (-right);
  213.   else if(!left.positive)
  214.     return -(-left + right);
  215.   else if (left < right)
  216.     return - (right - left);
  217.   int carry = 0;
  218.   for(int digit = 0; digit < right.length || carry; digit++){
  219.     left.number[digit] -= carry + (digit < right.length ? right.number[digit] : 0);
  220.     carry = (left.number[digit] < 0);
  221.     if(carry == 1){
  222.       left.number[digit] += 10;
  223.     }
  224.   }
  225.   left.length = left.number.size();
  226.   while(left.number.back() == 0 && left.number.size() > 1){
  227.     left.number.pop_back();
  228.   }
  229.   left.length = left.number.size();
  230.   if(left.number[0] == 0)
  231.     left.positive = true;
  232.   return left;
  233. }
  234. BigInteger operator* (const BigInteger& left, const BigInteger& right){
  235.   int max_size = (left.length >= right.length ? left.length : right.length);
  236.   std::vector<int> a = left.number;
  237.   std::vector<int> b = right.number;
  238.   BigInteger::extend(a, max_size);
  239.   BigInteger::extend(b, max_size);
  240.   std::vector<int> res = BigInteger::KaratsubaMultiplication(a, b);
  241.   for (int i = 0; i < res.size() - 1; ++i) {
  242.     res[i + 1] += res[i] / 10;
  243.     res[i] %= 10;
  244.   }
  245.   res.push_back(res.back() / 10);
  246.   while(res.size() > 1 && res.back() == 0)
  247.     res.pop_back();
  248.   BigInteger answer(res, left.positive == right.positive);
  249.   return answer;
  250. };
  251. BigInteger operator/ (const BigInteger& dividend, const BigInteger& divisor){
  252.   std::vector<int> answer (dividend.number.size());
  253.   bool sign = (dividend.positive == divisor.positive);
  254.   BigInteger dividend_ = dividend;
  255.   BigInteger divisor_ = divisor;
  256.   dividend_.positive = true;
  257.   divisor_.positive = true;
  258.   if(dividend_ < divisor_)
  259.     return(BigInteger(0));
  260.   for(int digit = (int)dividend.number.size() - 1; digit >= 0; --digit){
  261.     answer[digit] = 9;
  262.     while(BigInteger(answer,true) * divisor_ > dividend_ && answer[digit] > 0) {
  263.       answer[digit]--;
  264.     }
  265.   }
  266.   while(answer.back() == 0 && !answer.empty()) {
  267.     answer.pop_back();
  268.   }
  269.   return(BigInteger(answer,sign));
  270. }
  271. BigInteger operator% (const BigInteger& left, const BigInteger& right){
  272.   BigInteger quotient = left / right;
  273.   BigInteger answer = left - right * quotient;
  274.   return answer;
  275.  
  276. }
  277.  
  278. BigInteger& BigInteger::operator+=(const BigInteger& num) {
  279.   *this = *this + num;
  280.   return *this;
  281. }
  282. BigInteger& BigInteger::operator-=(const BigInteger& num) {
  283.   *this = *this - num;
  284.   return *this;
  285. }
  286. BigInteger& BigInteger::operator*=(const BigInteger& num){
  287.   *this = *this * num;
  288.   return *this;
  289. }
  290. BigInteger& BigInteger::operator/=(const BigInteger& num){
  291.   *this = *this / num;
  292.   return *this;
  293. }
  294. BigInteger& BigInteger::operator%=(const BigInteger& num){
  295.   *this = *this % num;
  296.   return *this;
  297. }
  298.  
  299.  
  300. void BigInteger::extend(std::vector<int>&a, int length){
  301.   while(length & (length - 1))
  302.     length++;
  303.   a.resize(length);
  304. }
  305. std::vector<int> BigInteger::NaiveMultiplication(std::vector<int>& left, std::vector<int>& right) {
  306.   int len = (left.size() >= right.size() ? left.size() : right.size());
  307.   len += len % 2;
  308.   while(left.size() < len)
  309.     left.push_back(0);
  310.   while(right.size() < len){
  311.     right.push_back(0);
  312.   }
  313.   std::vector<int> res(2 * len);
  314.  
  315.   for (int  i = 0; i < len; ++i) {
  316.     for (int j = 0; j < len; ++j) {
  317.       res[i + j] += left[i] * right[j];
  318.     }
  319.   }
  320.   return res;
  321. }
  322. std::vector<int> BigInteger::KaratsubaMultiplication(std::vector<int>& left, std::vector<int>& right) {
  323.   int len = (left.size() >= right.size() ? left.size() : right.size());
  324.   len += len % 2;
  325.   while(left.size() < len)
  326.     left.push_back(0);
  327.   while(right.size() < len){
  328.     right.push_back(0);
  329.   }
  330.   std::vector<int> result(2 * len);
  331.   if (len <= 2) {
  332.     return NaiveMultiplication(left, right);
  333.   }
  334.   int k = len / 2;
  335.  
  336.   std::vector<int> left_r{left.begin(), left.begin() + k};
  337.   std::vector<int> left_l{left.begin() + k, left.end()};
  338.   std::vector<int> right_r{right.begin(), right.begin() + k};
  339.   std::vector<int> right_l{right.begin() + k, right.end()};
  340.  
  341.   std::vector<int> P1 = KaratsubaMultiplication(left_l, right_l);
  342.   std::vector<int> P2 = KaratsubaMultiplication(left_r, right_r);
  343.  
  344.   std::vector<int> left_lr(k);
  345.   std::vector<int> right_rl(k);
  346.  
  347.   for (int i = 0; i < k; ++i) {
  348.     left_lr[i] = left_l[i] + left_r[i];
  349.     right_rl[i] = right_l[i] + right_r[i];
  350.   }
  351.  
  352.   std::vector<int> P3 = KaratsubaMultiplication(left_lr, right_rl);
  353.  
  354.   for (int i = 0; i < len; ++i) {
  355.     P3[i] -= P2[i] + P1[i];
  356.   }
  357.  
  358.   for (int i = 0; i < len; ++i) {
  359.     result[i] = P2[i];
  360.   }
  361.  
  362.   for (int i = len; i < 2 * len; ++i) {
  363.     result[i] = P1[i - len];
  364.   }
  365.  
  366.   for (int i = k; i < len + k; ++i) {
  367.     result[i] += P3[i - k];
  368.   }
  369.   return result;
  370. }
  371.  
Add Comment
Please, Sign In to add comment