Advertisement
Guest User

Untitled

a guest
Jun 19th, 2018
98
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.96 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <cstdlib>
  4. #include <limits>
  5. #include "BigInteger.h"
  6.  
  7. template<typename T, size_t Base>
  8. void BigInteger<T, Base>::update_digit(size_t index, T value) {
  9.         if (index / digits_capacity + 1 > digits.size())
  10.                 digits.resize(index / digits_capacity + 1);
  11.         T arr = digits[index / digits_capacity];
  12.         arr &= std::numeric_limits<T>::max() - (((1 << bits) - 1) << (bits * (index % digits_capacity)));
  13.         arr += value << (bits * (index % digits_capacity));
  14.         digits[index / digits_capacity] = arr;
  15. }
  16.  
  17. template<typename T, size_t Base>
  18. size_t BigInteger<T, Base>::size() const {
  19.         short i = 0;
  20.         for (T last = digits.back(); (last != 0); ++i, last >>= bits) {}
  21.         return (digits.size() - 1) * digits_capacity + i;
  22. }
  23.  
  24. template<typename T, size_t Base>
  25. bool BigInteger<T, Base>::abs_more(BigInteger<T, Base> const& b) {
  26.         if (size() > b.size()) return true;
  27.         if (b.size() > size()) return false;
  28.         for (ptrdiff_t i = b.size() - 1; i >= 0; --i)
  29.                 if ((*this)[i] != b[i]) return ((*this)[i] > b[i]);
  30.         return false;
  31. }
  32.  
  33. template<typename T, size_t Base>
  34. BigInteger<T, Base>::BigInteger() {
  35.         sign = true;
  36.         bool ones = false;
  37.         size_t temp = Base;
  38.         for (bits = 0; temp != 1; ++bits, temp >>= 1)
  39.                 if (temp & 1) ones = true;
  40.         bits += ones;
  41.         digits_capacity = std::numeric_limits<T>::digits / bits;
  42. }
  43.  
  44. template<typename T, size_t Base>
  45. template<typename NewT1, size_t NewBase>
  46. BigInteger<T, Base>::operator BigInteger<NewT1, NewBase>() {
  47.         BigInteger<NewT1, NewBase> b;
  48.         BigInteger<T, Base> numerator, temp;
  49.         numerator = *this;
  50.         b.sign = (*this).sign;
  51.         size_t digits_counter = 0;
  52.         while (numerator.size() > 1 || numerator[0] != 0) {
  53.                 if (numerator.digits.back() == 0) numerator.digits.resize(numerator.digits.size() - 1);
  54.                 temp.digits.resize(numerator.digits.size());
  55.                 size_t num;
  56.                 for (ptrdiff_t i = numerator.size() - 1; i >= 0; --i) {
  57.                         num = 0;
  58.                         for (size_t j = i; j < numerator.size(); ++j)
  59.                                 num += numerator[j] * pow(Base, j - i);
  60.                         if (num / NewBase) {
  61.                                 temp.update_digit(i, num / NewBase);
  62.                                 size_t temp_size = numerator.size();
  63.                                 for (size_t j = i; j < temp_size; ++j)
  64.                                         numerator.update_digit(j, (num % NewBase) % (int) pow(Base, j - i + 1) / pow(Base, j - i));
  65.                         }
  66.                 }
  67.                 b.update_digit(digits_counter++, num % NewBase);
  68.                 numerator.digits = temp.digits;
  69.                 temp.digits.clear();
  70.         }
  71.         return b;
  72. }
  73.  
  74. template<typename T, size_t Base>
  75. T BigInteger<T, Base>::operator [](size_t id) const {
  76.         T ans = digits[id / digits_capacity];
  77.         ans >>= bits * (id % digits_capacity);
  78.         ans = ans & ((1 << bits) - 1);
  79.         return ans;
  80. }
  81.  
  82. template<typename T, size_t Base>
  83. BigInteger<T, Base> BigInteger<T, Base>::operator -(){
  84.         BigInteger<T, Base> b = *this;
  85.         b.sign = !b.sign;
  86.         return b;
  87. }
  88.  
  89. template<typename T, size_t Base>
  90. BigInteger<T, Base> BigInteger<T, Base>::operator +(BigInteger<T, Base> b) {
  91.         if (sign != b.sign) return ((!sign) ? (b - -*this) : (*this - -b));
  92.         if ((*this).abs_more(b)) return b + *this;
  93.         unsigned int carry = 0;
  94.         for (size_t i = 0; i < std::max(b.size(), size()) || carry; ++i) {
  95.                 unsigned short temp = carry;
  96.                 carry = ((b[i] + carry + (i < size() ? (*this)[i] : 0)) >= Base);
  97.                 b.update_digit(i, b[i] + temp + (i < size() ? (*this)[i] : 0) + (carry ? -Base : 0));
  98.         }
  99.         return b;
  100. }
  101.  
  102. template<typename T, size_t Base>
  103. BigInteger<T, Base>& BigInteger<T, Base>::operator +=(BigInteger<T, Base>  b) {
  104.         *this = *this + b;
  105.         return *this;
  106. }
  107.  
  108. template<typename T, size_t Base>
  109. BigInteger<T, Base> BigInteger<T, Base>::operator -(BigInteger<T, Base> b) {
  110.         if (sign != b.sign) return ((!sign) ? (-(-*this + b)) : (*this + -b));
  111.         if (!sign) return (-b - -*this);
  112.         if (this->abs_more(b)) return (-(b - *this));
  113.         bool carry = false;
  114.         for (size_t i = 0; i < size() || carry; ++i) {
  115.                 ptrdiff_t c = ((ptrdiff_t) b[i] - carry - (ptrdiff_t)(i < size() ? (*this)[i] : 0));
  116.                 carry = c < 0;
  117.                 b.update_digit(i, c + (carry ? Base : 0));
  118.         }
  119.         size_t resize = b.digits.size();
  120.         while (b.digits[resize - 1] == 0 && resize > 1) --resize;
  121.         b.digits.resize(resize);
  122.         return -b;
  123. }
  124.  
  125. template<typename T, size_t Base>
  126. BigInteger<T, Base>& BigInteger<T, Base>::operator -=(BigInteger<T, Base> b) {
  127.         *this = *this - b;
  128.         return *this;
  129. }
  130.  
  131. template<typename T, size_t Base>
  132. std::istream& operator >>(std::istream& wave, BigInteger<T, Base>& b) {
  133.         std::string number;
  134.         wave >> number;
  135.         BigInteger<unsigned int, 10> temp;
  136.         if (number[0] == '-') {
  137.                 temp.sign = false;
  138.                 number = number.substr(1, number.length() - 1);
  139.         }
  140.         for (size_t i = 0; i < number.length(); ++i)
  141.                 temp.update_digit(i, stoi(number.substr(number.length() - i - 1, 1)));
  142.         b = BigInteger<T, Base>(temp);
  143.         return wave;
  144. }
  145.  
  146. template<typename T, size_t Base>
  147. std::ostream& operator <<(std::ostream& wave, BigInteger<T, Base> b) {
  148.         if (b.size() == 0) {
  149.                 wave << '0';
  150.                 return wave;
  151.         }
  152.         BigInteger<unsigned int, 10> temp = BigInteger<unsigned int, 10> (b);
  153.         if (!b.sign) wave << '-';
  154.         for (ptrdiff_t i = temp.size() - 1; i >= 0; --i) wave << temp[i];
  155.         return wave;
  156. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement