Advertisement
Kolyach

Untitled

Jun 2nd, 2019
290
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.47 KB | None | 0 0
  1. //******************************************************
  2. //Загаловочные файлы, использованные в реализации класса
  3. //******************************************************
  4. #include <iostream>
  5. #include <vector>
  6. #include <string>
  7. #include <algorithm>
  8. #include <iomanip>
  9.  
  10. using namespace std;
  11.  
  12. //*******************************
  13. //Класс, использованный в проекте
  14. //*******************************
  15.  
  16. class GiantInteger {
  17. private:
  18.     vector <int> number; // vector, хранящий по 9 цифр исходного числа в ячейке, записанных с конца для упрощения алгоритмов вычисления
  19.     bool negative; // флаг отрицательности числа. true - отрицательное, false - положительное
  20.     static const int basis = 1000000000; // ключевое слово static обеспечивает хранение данной переменной в памяти до непосредственного завершения программы
  21. public:
  22.     GiantInteger() {} // конструктор без параметров
  23.  
  24.     GiantInteger(string str) { // создание числа на основе переменной типа string
  25.         if (str.length() == 0) negative = false;
  26.         else {
  27.             if (str[0] == '-') {
  28.                 str = str.substr(1);
  29.                 negative = true;
  30.             }
  31.             else negative = false;
  32.         }
  33.         for (int i = str.length(); i > 0; i -= 9) {
  34.             if (i < 9) {
  35.                 number.push_back(atoi(str.substr(0, i).c_str())); // функция c_str() используется, поскольку функция atoi принимает на вход указатель на string
  36.             }
  37.             else number.push_back(atoi(str.substr(i-9, 9).c_str()));
  38.         }
  39.     }
  40.    
  41.     ~GiantInteger() {} // деструктор класса
  42.  
  43.     friend ostream& operator <<(ostream& out, const GiantInteger& num) { // перегрузка оператора вывода
  44.         if (num.number.empty()) out << 0;
  45.         else {
  46.             if (num.negative) out << '-';
  47.             out << num.number.back();
  48.             char old_fill = out.fill('0'); // задаётся символ заполнения, который заполняет места удалённых нолей
  49.             for (int i = num.number.size() - 2; i >= 0; --i) {
  50.                 out << setw(9) << num.number[i]; // задаётся вывод шириной в 9 символов, именно столько хранится в одной ячейке вектора number
  51.             }
  52.             out.fill(old_fill); // возврат стандартного символа заполнения
  53.         }
  54.         return out;
  55.     }
  56.  
  57.     friend bool operator ==(const GiantInteger& left, const GiantInteger& right) { // перегрузка оператора равенства
  58.         if (left.negative != right.negative) return false;
  59.         if (left.number.empty()) {
  60.             if (right.number.empty() || (right == 0)) return true;
  61.             else return false;
  62.         }
  63.         if (right.number.empty()) {
  64.             if (left == 0) return true;
  65.             else return false;
  66.         }
  67.         if (left.number.size() != right.number.size()) return false;
  68.         for (int i = 0; i < left.number.size(); ++i) if (left.number[i] != right.number[i]) return false;
  69.         return true;
  70.     }
  71.  
  72.     friend bool operator !=(const GiantInteger& left, const GiantInteger& right) { // перегрузка оператора неравенства
  73.         return !(left == right);
  74.             }
  75.    
  76.     friend bool operator <(const GiantInteger& left, const GiantInteger& right) { // перегрузка оператора меньше
  77.         if (left == right) return false;
  78.         if (left.negative) {
  79.             if (right.negative) return ((-right) < (-left));
  80.             else return true;
  81.         }
  82.         else if (right.negative) return false;
  83.         else {
  84.             if (left.number.size() != right.number.size()) {
  85.                 return left.number.size() < right.number.size();
  86.             }
  87.             else {
  88.                 for (int i = left.number.size() - 1; i >= 0; --i) {
  89.                     if (left.number[i] != right.number[i]) return left.number[i] < right.number[i];
  90.                 }
  91.                 return false;
  92.             }
  93.         }
  94.     }
  95.  
  96.     friend bool operator <=(const GiantInteger& left, const GiantInteger& right) { // перегрузка оператора меньше или равно
  97.         return (left < right || left == right);
  98.     }
  99.  
  100.     GiantInteger operator = (const GiantInteger& num) { // перегрузка оператора присваивания
  101.         negative = num.negative;
  102.         number = num.number;
  103.         return num;
  104.     }
  105.  
  106.     void RemoveZeros() { // функция по удалению ведущих нулей
  107.         while (number.size() > 1 && number.back() == 0) {
  108.             number.pop_back();
  109.         }
  110.         if (number.size() == 1 && number[0] == 0) negative = false;
  111.     }
  112.  
  113.     GiantInteger operator - () const { // перегрузка оператора унарный минус
  114.         GiantInteger copy(*this);
  115.         copy.negative = !copy.negative;
  116.         return copy;
  117.     }
  118.  
  119.     friend const GiantInteger operator + (GiantInteger left, GiantInteger right) { // перегрузка оператора сложения
  120.         int carry = 0; // остаток
  121.         if (left.negative) {
  122.             if (right.negative) return -(-left + (-right));
  123.             else return right - (-left);
  124.         }
  125.         else if (right.negative) return left - (-right);
  126.         else {
  127.             for (int i = 0; i < max(left.number.size(), right.number.size()) || carry != 0; ++i) {
  128.                 if (i == left.number.size()) left.number.push_back(0);
  129.                 left.number[i] += carry + (i < right.number.size() ? right.number[i] : 0); // тернарная условная операция
  130.                 carry = left.number[i] >= basis;
  131.                 if (carry != 0) left.number[i] -= basis;
  132.             }
  133.         }
  134.         return left;
  135.     }
  136.  
  137.     friend const GiantInteger operator -(GiantInteger left, GiantInteger right) { // перегрузка оператора вычитания
  138.         if (right.negative) return left + (-right);
  139.         else if (left.negative) return -(-left + right);
  140.         else if (left < right) return -(right - left);
  141.         int carry = 0;
  142.         for (int i = 0; i < right.number.size() || carry != 0; ++i) {
  143.             left.number[i] -= carry + (i < right.number.size() ? right.number[i] : 0);
  144.             carry = left.number[i] < 0;
  145.             if (carry != 0) left.number[i] += basis;
  146.         }
  147.         left.RemoveZeros(); // удаление ведущих нулей
  148.         return left;
  149.     }
  150.  
  151.     friend const GiantInteger operator *(const GiantInteger& left, const GiantInteger& right) { // перегрузка оператора умножения
  152.         GiantInteger result;
  153.         result.number.resize(left.number.size() + right.number.size());
  154.         for (int i = 0; i < left.number.size(); ++i) {
  155.             int carry = 0;
  156.             for (int j = 0; j < right.number.size() || carry != 0; ++j) {
  157.                 long long cur = result.number[i + j] + left.number[i] * 1LL * (j < right.number.size() ? right.number[j] : 0) + carry;
  158.                 result.number[i + j] = static_cast<int>(cur % basis);
  159.                 carry = static_cast<int>(cur / basis);
  160.             }
  161.         }
  162.         result.negative = left.negative != right.negative;
  163.         result.RemoveZeros();
  164.         return result;
  165.     }
  166.  
  167.     GiantInteger (int l) { // конструктор объекта класса на основне переменной класса int
  168.         if (l < 0) { this->negative = true; l = -l; }
  169.         else this->negative = false;
  170.         do {
  171.             this->number.push_back(l % basis);
  172.             l /= basis;
  173.         } while (l != 0);
  174.     }
  175.  
  176.     void Shift() { // функция сдвига вправо, использующаяся в алгоритме деления
  177.         if (number.size() == 0) {
  178.             number.push_back(0);
  179.             return;
  180.         }
  181.         number.push_back(number[number.size() - 1]);
  182.         for (int i = number.size() - 2; i > 0; --i) number[i] = number[i - 1];
  183.         number[0] = 0;
  184.     }
  185.  
  186.     friend const GiantInteger operator /(const GiantInteger& left, const GiantInteger& right) { // перегрузка оператора деления
  187.         if (right == 0) {
  188.             return left;
  189.         }
  190.         GiantInteger b = right;
  191.         b.negative = false;
  192.         GiantInteger result, current;
  193.         result.number.resize(left.number.size());
  194.         for (int i = (left.number.size()) - 1; i >= 0; --i) {
  195.             current.Shift();
  196.             current.number[0] = left.number[i];
  197.             current.RemoveZeros();
  198.             int x = 0, l = 0, r = basis;
  199.             while (l <= r) { // алгоритм поиска максимального делителя
  200.                 int m = (l + r) / 2;
  201.                 GiantInteger t = b * m;
  202.                 if (t <= current) {
  203.                     x = m;
  204.                     l = m + 1;
  205.                 }
  206.                 else r = m - 1;
  207.             }
  208.             result.number[i] = x; // записываем найденныый делитель
  209.             current = current - b * x;
  210.         }
  211.         result.negative = left.negative != right.negative;
  212.         result.RemoveZeros();
  213.         return result;
  214.     }
  215. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement