Advertisement
Guest User

BigInteger.cpp

a guest
May 23rd, 2018
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.23 KB | None | 0 0
  1. #include "BigInteger.hpp"
  2. #include <string>
  3. #include <cstdlib>
  4. #include <algorithm>
  5. #include <cmath>
  6. #include <vector>
  7.  
  8. const int standartBase = (int)1e9;
  9. const int step = 9;
  10.  
  11. using namespace std;
  12. template<typename T, size_t Base>
  13. BigInteger<T, Base>::BigInteger(long long val) {
  14.     sign = val < 0 ? -1 : 1;
  15.     val *= sign;
  16.     number.clear();
  17.     size_of_number = 0;
  18.     std::vector<T> buf(0);
  19.     while (val > 0) {
  20.         for (size_t i = 0; i < num_of_blocks && val > 0; i++) {
  21.             buf.push_back(val % Base);
  22.             size_of_number++;
  23.             val /= Base;
  24.         }
  25.         std::reverse(buf.begin(), buf.end());
  26.         T cur = 0;
  27.         for (size_t i = 0; i < buf.size(); i++) {
  28.             cur = cur << num_of_bits;
  29.             cur = cur | buf[i];
  30.         }
  31.         number.push_back(cur);
  32.         buf.clear();
  33.     }
  34.     clear();
  35. }
  36.  
  37. template<typename T, size_t Base>
  38. BigInteger<T, Base>::BigInteger(const std::vector<T>& number, const int sign) {
  39.  
  40.     this->number = number;
  41.     this->sign = sign;
  42.     clear();
  43. }
  44.  
  45. template<typename T, size_t Base>
  46. BigInteger<T, Base>::BigInteger(const std::string &s) {
  47.     std::vector<int> v(0);
  48.     int pos = 0;
  49.     sign = 1;
  50.     if (s[pos] == '-') {
  51.         sign = -1;
  52.         pos++;
  53.     }
  54.     for (int i = (int)s.size() - 1; i >= pos; i -= step) {
  55.         int digit = 0;
  56.         for (int j = std::max(pos, i - step + 1); j <= i; j++) {
  57.             digit = digit * 10 + (int)(s[j] - '0');
  58.         }
  59.         v.push_back(digit);
  60.     }
  61.  
  62.     while (!v.empty() && v.back() == 0) {
  63.         v.pop_back();
  64.     }
  65.     *this = static_cast<BigInteger<T, Base>>(BigInteger<int, standartBase>(v, sign));
  66. }
  67.  
  68. template<typename T, size_t Base>
  69. BigInteger<T, Base>::BigInteger(const BigInteger &val) {
  70.     number = val.number;
  71.     sign = val.sign;
  72.     size_of_number = val.size_of_number;
  73. }
  74.  
  75. template<typename T, size_t Base>
  76. BigInteger<T, Base>::BigInteger(BigInteger &&val) {
  77.     number = std::move(val.number);
  78.     sign = val.sign;
  79.     size_of_number = val.size_of_number;
  80. }
  81.  
  82. template<typename T, size_t Base>
  83. size_t BigInteger<T, Base>::Size() const {
  84.     return size_of_number;
  85. }
  86.  
  87. template<typename T, size_t Base>
  88. T BigInteger<T, Base>::operator[](size_t id) const {
  89.     size_t pos = id / num_of_blocks;
  90.     size_t shift = id % num_of_blocks;
  91.     T cur = number[pos] >> (num_of_bits * shift);
  92.     T mask = (T(1) << num_of_bits) - 1;
  93.     T res = cur & mask;
  94.     return res;
  95. }
  96.  
  97. template<typename T, size_t Base>
  98. template<typename NewT, size_t NewBase>
  99. BigInteger<T, Base>::operator BigInteger<NewT, NewBase>() {
  100.     BigInteger<NewT, 10> pow(1);
  101.     BigInteger<NewT, 10> result(0);
  102.     BigInteger<NewT, 10> base(Base);
  103.  
  104.     for (size_t i = 0; i < Size(); i++) {
  105.         BigInteger<NewT, 10> digit((*this)[i]);
  106.         BigInteger<NewT, 10> buffer = digit * pow;
  107.         result += buffer;
  108.         pow *= base;
  109.     }
  110.  
  111.     NewT num = 0;
  112.     std::vector<NewT> buffer;
  113.     size_t new_num_of_bits = ceil(log2(NewBase));
  114.     size_t new_num_of_blocks = sizeof(NewT) * 8 / new_num_of_bits;
  115.  
  116.     int index = 0;
  117.     NewT path = 0;
  118.     while (result.Size() > 0) {
  119.         path = (result % NewBase);
  120.         result /= NewBase;
  121.         num += (path << (index % new_num_of_blocks) * new_num_of_bits);
  122.         if (index % new_num_of_blocks == new_num_of_blocks - 1) {
  123.             buffer.push_back(num);
  124.             num = 0;
  125.         }
  126.         index++;
  127.     }
  128.     if (num != 0) {
  129.         buffer.push_back(num);
  130.     }
  131.     BigInteger<NewT, NewBase> ans(buffer, sign);
  132.     return ans;
  133. }
  134.  
  135. template<typename T, size_t Base>
  136. BigInteger<T, Base>& BigInteger<T, Base>::operator = (BigInteger<T, Base> val) {
  137.     number = val.number;
  138.     sign = val.sign;
  139.     size_of_number = val.size_of_number;
  140.     return *this;
  141. }
  142.  
  143. template<typename T, size_t Base>
  144. bool BigInteger<T, Base>::operator < (const BigInteger &val) const {
  145.     if (sign != val.sign)
  146.         return sign < val.sign;
  147.     if (Size() != val.Size())
  148.         return sign >= 0 ? Size() < val.Size() : Size() > val.Size();
  149.     for (int i = int(val.Size()) - 1; i >= 0; i--)
  150.         if ((*this)[i] != val[i])
  151.             return (*this)[i] * sign < val[i] * val.sign;
  152.     return false;
  153. }
  154.  
  155.  
  156. template<typename T, size_t Base>
  157. bool BigInteger<T, Base>::operator == (const BigInteger &val) const {
  158.     return !(*this < val) && !(val < *this);
  159. }
  160.  
  161. template<typename T, size_t Base>
  162. bool BigInteger<T, Base>::operator != (const BigInteger & val) const
  163. {
  164.     return !(*this == val);
  165. }
  166.  
  167. template<typename T, size_t Base>
  168. bool BigInteger<T, Base>::operator>(const BigInteger &val) const {
  169.     return !(*this == val) && !(*this < val);
  170. }
  171.  
  172. template<typename T, size_t Base>
  173. bool BigInteger<T, Base>::operator<=(const BigInteger &val) const {
  174.     return (*this < val) || (*this == val);
  175. }
  176.  
  177. template<typename T, size_t Base>
  178. bool BigInteger<T, Base>::operator>=(const BigInteger &val) const {
  179.     return (*this > val) || (*this == val);
  180. }
  181.  
  182. template<typename T, size_t Base>
  183. BigInteger<T, Base> BigInteger<T, Base>::abs() const
  184. {
  185.     BigInteger<T, Base> buffer = *this;
  186.     if (buffer.sign == -1) {
  187.         buffer.sign = 1;
  188.     }
  189.     return buffer;
  190. }
  191.  
  192. template<typename T, size_t Base>
  193. BigInteger<T, Base> & BigInteger<T, Base>::operator += (const BigInteger & val)
  194. {
  195.     if (sign == val.sign) {
  196.         T carry = 0;
  197.         size_t len_of_this = number.size();
  198.         for (size_t i = 0; i < std::max(val.number.size(), len_of_this) || carry; i++) {
  199.             if (i == number.size()) {
  200.                 number.push_back(0);
  201.                 size_of_number += num_of_blocks;
  202.             }
  203.             T num = 0;
  204.             if (i < len_of_this) {
  205.                 if (i < val.number.size()) {
  206.                     for (size_t j = 0; j < num_of_blocks; j++) {
  207.                         T first = val[i * num_of_blocks + j];
  208.                         T second = (*this)[i * num_of_blocks + j];
  209.                         if (first >= T(Base) - T(carry) - second) {
  210.                             num = num + ((first - T(Base) + second + carry) << j * num_of_bits);
  211.                             carry = 1;
  212.                         }
  213.                         else {
  214.                             num += ((first + second + carry) << j * num_of_bits);
  215.                             carry = 0;
  216.                         }
  217.                     }
  218.                 }
  219.                 else {
  220.                     for (size_t j = 0; j < num_of_blocks; j++) {
  221.                         T first = (*this)[i * num_of_blocks + j];
  222.                         if (first >= T(Base) - carry) {
  223.                             num += ((first - (T)(Base)+carry) << j * num_of_bits);
  224.                             carry = 1;
  225.                         }
  226.                         else {
  227.                             num += ((first + carry) << j * num_of_bits);
  228.                             carry = 0;
  229.                         }
  230.                     }
  231.                 }
  232.             }
  233.             else if (i < val.number.size()) {
  234.                 for (size_t j = 0; j < num_of_blocks; j++) {
  235.                     T first = val[i * num_of_blocks + j];
  236.                     if (first >= T(Base) - carry) {
  237.                         num += ((first + (-(T)Base + carry)) << j * num_of_bits);
  238.                         carry = 1;
  239.                     }
  240.                     else {
  241.                         num += ((first + carry) << j * num_of_bits);
  242.                         carry = 0;
  243.                     }
  244.                 }
  245.             }
  246.             else {
  247.                 num = carry;
  248.                 carry = 0;
  249.             }
  250.             number[i] = num;
  251.         }
  252.         clear();
  253.         return *this;
  254.     }
  255.     else {
  256.         (*this) -= (-val);
  257.         clear();
  258.         return *this;
  259.     }
  260. }
  261.  
  262. template<typename T, size_t Base>
  263. BigInteger<T, Base> BigInteger<T, Base>::operator + (const BigInteger & val) const
  264. {
  265.     BigInteger<T, Base> buffer = *this;
  266.     buffer += val;
  267.     return buffer;
  268. }
  269.  
  270. template<typename T, size_t Base>
  271. BigInteger<T, Base> & BigInteger<T, Base>::operator -= (const BigInteger & val)
  272. {
  273.     if (sign == val.sign) {
  274.         if ((*this).abs() >= val.abs()) {
  275.             T carry = 0;
  276.             for (size_t i = 0; i < val.number.size() || carry; i++) {
  277.                 T num = 0;
  278.                 if (i < val.number.size()) {
  279.                     for (size_t j = 0; j < num_of_blocks; j++) {
  280.                         T first = (*this)[i * num_of_blocks + j];
  281.                         T second = val[i * num_of_blocks + j];
  282.                         if (first < second + carry) {
  283.                             num += (((T(Base) - carry - second) + first) << j * num_of_bits);
  284.                             carry = 1;
  285.                         }
  286.                         else {
  287.                             num += ((first - second - carry) << j * num_of_bits);
  288.                             carry = 0;
  289.                         }
  290.                     }
  291.                 }
  292.                 else {
  293.                     for (size_t j = 0; j < num_of_blocks; j++) {
  294.                         T first = (*this)[i * num_of_blocks + j];
  295.                         if (first < carry) {
  296.                             num += ((T(Base) - carry + first) << j * num_of_bits);
  297.                             carry = 1;
  298.                         }
  299.                         else {
  300.                             num += ((first - carry) << j * num_of_bits);
  301.                             carry = 0;
  302.                         }
  303.                     }
  304.                 }
  305.                 (*this).number[i] = num;
  306.             }
  307.             clear();
  308.             return *this;
  309.         }
  310.         else {
  311.             *this = (-(val - *this));
  312.             clear();
  313.             return *this;
  314.         }
  315.     }
  316.     else {
  317.         *this = *this + (-val);
  318.         clear();
  319.         return *this;
  320.     }
  321. }
  322.  
  323. template<typename T, size_t Base>
  324. BigInteger<T, Base> BigInteger<T, Base>::operator - (const BigInteger & val) const
  325. {
  326.     BigInteger<T, Base> buffer = *this;
  327.     buffer -= val;
  328.     return buffer;
  329. }
  330.  
  331. template<typename T, size_t Base>
  332. BigInteger<T, Base> & BigInteger<T, Base>::operator *= (const BigInteger & val)
  333. {
  334.     BigInteger<T, Base> val1 = val;
  335.     *this = *this * val1;
  336.     return *this;
  337. }
  338.  
  339. template<typename T, size_t Base>
  340. BigInteger<T, Base> BigInteger<T, Base>::operator * (const BigInteger & val)
  341. {
  342.     vector<T> res(Size() + val.Size());
  343.     vector<T> first(Size());
  344.     vector<T> second(val.Size());
  345.  
  346.     for (int i = 0; i < (int)first.size(); i++) {
  347.         first[i] = (*this)[i];
  348.     }
  349.     for (int i = 0; i < (int)second.size(); i++) {
  350.         second[i] = val[i];
  351.     }
  352.     for (int i = 0; i < (int)first.size(); i++) {
  353.         long long carry = 0;
  354.         for (int j = 0; j < (int)second.size() || carry; j++) {
  355.             long long cur = (long long)res[i + j] + ((long long)first[i] * (long long)(j < (int)second.size() ? second[j] : 0) + carry);
  356.             res[i + j] = (T)(cur % Base);
  357.             carry = (T)(cur / Base);
  358.         }
  359.     }
  360.  
  361.     while (!res.empty() && res.back() == (T)0) {
  362.         res.pop_back();
  363.     }
  364.  
  365.     vector<T> buf;
  366.     T num = 0;
  367.     for (size_t i = 0; i < res.size(); i++) {
  368.         num += (res[i] << ((i % num_of_blocks) * num_of_bits));
  369.         if (i % num_of_blocks == num_of_blocks - 1) {
  370.             buf.push_back(num);
  371.             num = 0;
  372.         }
  373.     }
  374.  
  375.     if (num != 0) {
  376.         buf.push_back(num);
  377.     }
  378.  
  379.     BigInteger<T, Base> ans(buf, sign == val.sign ? 1 : -1);
  380.     ans.clear();
  381.     return ans;
  382. }
  383.  
  384. template<typename T, size_t Base>
  385. BigInteger<T, Base> BigInteger<T, Base>::operator * (long long val)
  386. {
  387.     return *this * BigInteger<long long> (val);
  388. }
  389.  
  390. template<typename T, size_t Base>
  391. BigInteger<T, Base> & BigInteger<T, Base>::operator *= (long long val)
  392. {
  393.     *this = *this * BigInteger<long long> (val);
  394.     return *this;
  395. }
  396.  
  397. template<typename T, size_t Base>
  398. BigInteger<T, Base> & BigInteger<T, Base>::operator /= (long long val)
  399. {
  400.     if (Size() == 0) {
  401.         return *this;
  402.     }
  403.  
  404.     if (val < 0) {
  405.         sign *= -1;
  406.         val *= -1;
  407.     }
  408.     unsigned long long path = 0;
  409.     T num = 0;
  410.     int index = number.size() - 1;
  411.     for (int i = int(Size()) - 1; i >= 0; i--) {
  412.         unsigned long long cur = path * Base + (*this)[i];
  413.         path = cur % val;
  414.         num += (T(cur / val) << ((i % num_of_blocks) * num_of_bits));
  415.         if (i % num_of_blocks == 0) {
  416.             number[index] = num;
  417.             num = 0;
  418.             index--;
  419.         }
  420.     }
  421.     (*this).clear();
  422.     return *this;
  423. }
  424.  
  425. template<typename T, size_t Base>
  426. BigInteger<T, Base> BigInteger<T, Base>::operator / (long long val) const
  427. {
  428.     BigInteger<T, Base> buffer = *this;
  429.     buffer /= val;
  430.     return buffer;
  431. }
  432.  
  433.  
  434. template<typename T, size_t Base>
  435. long long BigInteger<T, Base>::operator%(long long val) const {
  436.     if (Size() == 0) {
  437.         return 0;
  438.     }
  439.     unsigned long long path = 0;
  440.     for (int i = int(Size()) - 1; i >= 0; i--) {
  441.         path = (path * Base + (*this)[i]) % val;
  442.     }
  443.     return path;
  444. }
  445.  
  446. template<typename T, size_t Base>
  447. BigInteger<T, Base> BigInteger<T, Base>::operator - () const
  448. {
  449.     BigInteger<T, Base> buffer = *this;
  450.     buffer.sign = -sign;
  451.     return buffer;
  452. }
  453.  
  454. template<typename T, size_t Base>
  455. void BigInteger<T, Base>::clear()
  456. {
  457.     while (!number.empty() && number.back() == 0) {
  458.         number.pop_back();
  459.     }
  460.     size_of_number = num_of_blocks * number.size();
  461.     while (!number.empty() && (*this)[size_of_number - 1] == 0)
  462.         size_of_number--;
  463.     if (number.empty()) {
  464.         sign = 1;
  465.     }
  466. }
  467.  
  468. template<typename T, size_t Base>
  469. std::ostream & operator<<(std::ostream &os, BigInteger<T, Base> &val) {
  470.     auto tmp = static_cast<BigInteger<int, 10>>(val);
  471.     auto Zero = BigInteger<int, 10>(0);
  472.     if (tmp < Zero) {
  473.         os << '-';
  474.     }
  475.     if (tmp.Size() == 0) {
  476.         os << 0;
  477.     }
  478.     else {
  479.         for (int i = (int)tmp.Size() - 1; i >= 0; i--) {
  480.             os << tmp[i];
  481.         }
  482.     }
  483.     return os;
  484. }
  485.  
  486. template<typename T, size_t Base>
  487. std::istream & operator>>(std::istream &is, BigInteger<T, Base> &val) {
  488.     std::string s;
  489.     is >> s;
  490.     BigInteger<T, Base> buffer = BigInteger<T, Base>(s);
  491.     val = buffer;
  492.     return is;
  493. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement