Advertisement
Toliak

lab8 (final (i guess))

Nov 28th, 2018
394
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 25.42 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <vector>
  4. #include <cstring>              // Для std::memset, std::memcpy
  5. #include <cassert>              // Для assert
  6. #include <map>                  // Для std::map
  7. #include <functional>           // Для std::bit_and, std::bit_xor, и т.п.
  8. #include <type_traits>          // Для проверки типов
  9.  
  10. /*
  11.  * Использована структура
  12.  * Использованы assert'ы для выброса исключений
  13.    (т.к. мы еще не умеем пользоваться классами => наследоваться => создавать свои исключения)
  14.  * Использованы шаблоны функций (и их спецификация)
  15.  * Использованы методы структур
  16.  * Использована перегрузка функций операторов
  17.  * Использована работа с памятью в стиле Си
  18.  * Использованы функторы (объект с перегруженным operator() ) из <functional>
  19. */
  20.  
  21. // unsigned number (24 Байта)
  22. struct BigUInt192
  23. {
  24.     using baseType = uint16_t;          // Базовый тип (для хранения)
  25.     using oversizedType = uint32_t;     // Тип для вычислений
  26.  
  27.     static_assert(sizeof(baseType) < sizeof(oversizedType), "Size of oversizedType must be greater");
  28.     static_assert(std::is_arithmetic<baseType>::value, "baseType must be arithmetic");
  29.     static_assert(std::is_unsigned<baseType>::value, "baseType must be unsigned");
  30.     static_assert(std::is_arithmetic<oversizedType>::value, "oversizedType must be arithmetic");
  31.     static_assert(std::is_unsigned<oversizedType>::value, "oversizedType must be unsigned");
  32.  
  33.     // Стандартный конструктор
  34.     // Созданное число - 0
  35.     BigUInt192()
  36.     {
  37.         parts = new baseType[arraySize];            // Выделяем память
  38.         this->erase();                              // Инициализируем 0
  39.     }
  40.  
  41.     // Конструктор копирования
  42.     BigUInt192(const BigUInt192 &original)
  43.         : BigUInt192()
  44.     {
  45.         // Копируем область памяти
  46.         std::memcpy(parts, original.parts, sizeof(baseType) * arraySize);
  47.     }
  48.  
  49.     // Конструктор, инициализирующий 0ю ячейку
  50.     explicit BigUInt192(const baseType &original)
  51.         : BigUInt192()
  52.     {
  53.         parts[0] = original;
  54.     }
  55.  
  56.     // Шаблонная функция (шаблон задает систему счисления)
  57.     // Парсит строку в себя
  58.     template<int T>
  59.     void fromString(const std::string &str)
  60.     {
  61.         // Управление сюда передаваться не должно
  62.         assert(false);  // Выкидываем ошибку
  63.     }
  64.  
  65.     // Очистка памяти, выделенной под данные
  66.     void erase()
  67.     {
  68.         std::memset(parts, 0, sizeof(baseType) * arraySize);
  69.     }
  70.  
  71.     // Шаблонная функция
  72.     // Применяет функтор к каждому блоку данных
  73.     template<template<class> class F, class T>
  74.     BigUInt192 applyBlock(F<T> functor) const
  75.     {
  76.         BigUInt192 result;
  77.         for (size_t i = 0; i < arraySize; i++) {
  78.             result.parts[i] = functor(parts[i]);
  79.         }
  80.         return result;
  81.     }
  82.  
  83.     // Шаблонная функция
  84.     // Применяет функтор к каждому блоку данных попарно
  85.     // Вообще говоря, не коммутативна
  86.     template<template<class> class F, class T>
  87.     BigUInt192 applyBlock(const BigUInt192 &right, F<T> functor) const
  88.     {
  89.         BigUInt192 result;
  90.         for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  91.             result.parts[i] = functor(parts[i], right.parts[i]);
  92.         }
  93.         return result;
  94.     }
  95.  
  96.     // Сдвиг
  97.     // Вынесено в отдельную функцию из-за некоторых повторяющихся блоков кода
  98.     // Например: генерация маски и процесс сдвига для циклического сдвига
  99.     BigUInt192 shift(char way, size_t amount, bool circled) const
  100.     {
  101.         // Маска
  102.         baseType mask = 0x0;
  103.         for (size_t i = 0; i < amount; i++) {
  104.             mask = static_cast<BigUInt192::baseType>(mask << 1 | 1);
  105.         }
  106.  
  107.         BigUInt192 result;                  // Результат
  108.         baseType last = 0;                  // Биты для переноса в другой блок
  109.         if (way == 0) {                     // <<
  110.             for (size_t i = 0; i < arraySize; i++) {
  111.                 result.parts[i] = (parts[i] << amount) | last;
  112.                 last = (parts[i] >> (8 * sizeof(baseType) - amount)) & mask;
  113.             }
  114.         } else {                            // >>
  115.             for (size_t i = 0; i < arraySize; i++) {
  116.                 const size_t index = arraySize - i - 1;
  117.                 result.parts[index] = (parts[index] >> amount);
  118.                 result.parts[index] |= last << (8 * sizeof(baseType) - amount);
  119.                 last = parts[index] & mask;
  120.             }
  121.         }
  122.  
  123.         // Для циклического сдвига
  124.         if (circled) {
  125.             if (way == 0)                   // <<
  126.                 result.parts[0] |= last;
  127.             else                            // >>
  128.                 result.parts[arraySize - 1] |= last << (8 * sizeof(baseType) - amount);
  129.         }
  130.  
  131.         return result;
  132.     }
  133.  
  134.     // Циклический <<
  135.     BigUInt192 shiftCircleL(size_t amount)
  136.     {
  137.         return shift(0, amount, true);
  138.     }
  139.  
  140.     // Циклический >>
  141.     BigUInt192 shiftCircleR(size_t amount)
  142.     {
  143.         return shift(1, amount, true);
  144.     }
  145.  
  146.     // friend функции, имеющие доступ к private членам структуры
  147.     // Однако, мы не знаем, что такое модификаторы доступа
  148.     // В контексте этого кода используются как описания функций, объявленных после структуры
  149.  
  150.     friend BigUInt192 &operator+=(BigUInt192 &, const BigUInt192 &);
  151.     friend BigUInt192 operator+(const BigUInt192 &, const BigUInt192 &);
  152.     friend BigUInt192 &operator-=(BigUInt192 &, const BigUInt192 &);
  153.     friend BigUInt192 operator-(const BigUInt192 &, const BigUInt192 &);
  154.     friend bool operator>(const BigUInt192 &, const BigUInt192 &);
  155.     friend bool operator==(const BigUInt192 &, const BigUInt192 &);
  156.     friend bool operator!=(const BigUInt192 &, const BigUInt192 &);
  157.     friend bool operator<(const BigUInt192 &, const BigUInt192 &);
  158.     friend bool operator<=(const BigUInt192 &, const BigUInt192 &);
  159.     friend bool operator>=(const BigUInt192 &, const BigUInt192 &);
  160.     friend BigUInt192 operator&(const BigUInt192 &, const BigUInt192 &);
  161.     friend BigUInt192 operator|(const BigUInt192 &, const BigUInt192 &);
  162.     friend BigUInt192 operator^(const BigUInt192 &, const BigUInt192 &);
  163.     friend BigUInt192 operator~(const BigUInt192 &);
  164.     friend BigUInt192 operator<<(const BigUInt192 &, size_t);
  165.     friend BigUInt192 operator>>(const BigUInt192 &, size_t);
  166.     friend std::istream &operator>>(std::istream &, BigUInt192 &);
  167.     friend std::ostream &operator<<(std::ostream &, const BigUInt192 &);
  168.  
  169.     // Умножение через сложение
  170.     // Замечание: такое умножение не коммутативно относительно времени выполнения
  171.     BigUInt192 &multiplySlow(const BigUInt192 &right)
  172.     {
  173.         // Умножение на 0 ожидаемо дает 0
  174.         if (right == BigUInt192(0)) {
  175.             erase();
  176.             return *this;
  177.         }
  178.  
  179.         BigUInt192 original(*this);     // Копия себя
  180.         BigUInt192 one(1);              // Единица (чтобы постоянно 24 Байта не выделять)
  181.         for (BigUInt192 i; i < right - one; i += one) {
  182.             *this += original;
  183.         }
  184.         return *this;
  185.     }
  186.  
  187.     // Шаблонная функция (шаблон задает систему счисления)
  188.     // Преобразует число в строку
  189.     template<int T>
  190.     std::string toString() const
  191.     {
  192.         // Управление сюда передаваться не должно
  193.         assert(false);  // Выкидываем ошибку
  194.     }
  195.  
  196.     // Деструктор
  197.     ~BigUInt192()
  198.     {
  199.         delete[] parts;     // Очистка памяти
  200.     }
  201.  
  202.     // Количество байт (размер типа)
  203.     static const size_t bytes = 24;
  204.     // Размер массива (для выделения памяти)
  205.     static const size_t arraySize = bytes / sizeof(baseType) + (bytes % sizeof(baseType) > 0);
  206.  
  207.     // Хранит данные о числе
  208.     baseType *parts;
  209. };
  210.  
  211. // Преобразование из строки 10-чной системы
  212. template<>
  213. void BigUInt192::fromString<10>(const std::string &str)
  214. {
  215.     // Подготовка
  216.     erase();
  217.  
  218.     // Множитель
  219.     BigUInt192 multiplier(1);
  220.     BigUInt192 multiplierCoeff(10);         // Коэффициент умножения
  221.  
  222.     for (auto it = str.crbegin(); it != str.crend(); it++) {
  223.         // Цифра в 10й системе
  224.         const BigUInt192 numeral = BigUInt192(static_cast<baseType>(*it - '0'));
  225.  
  226.         // Копирование
  227.         // Необходимо для умножения 10**k * n
  228.         // Т.е. n раз прибавим 10**k , где 0 <= n <= 9
  229.         BigUInt192 multiplierCopy = multiplier;
  230.  
  231.         // Операции
  232.         *this += multiplierCopy.multiplySlow(numeral);
  233.         multiplier.multiplySlow(multiplierCoeff);       // Увеличиваем множитель
  234.     }
  235. }
  236.  
  237. // Преобразование из строки 16-чной системы
  238. template<>
  239. void BigUInt192::fromString<16>(const std::string &str)
  240. {
  241.     erase();
  242.     for (auto it = str.crbegin(); it != str.crend(); it++) {
  243.         if (*it == '0')
  244.             continue;
  245.         const size_t i = static_cast<size_t>(it - str.crbegin());       // Индекс символа через итераторы
  246.  
  247.         // Преобразуем цифру/букву из символа в число
  248.         std::stringstream stream;
  249.         baseType numeral;               // Для числа
  250.         stream << std::nouppercase << *it;
  251.         stream >> std::hex >> numeral;
  252.  
  253.         const size_t index = i / (sizeof(baseType) * 2);                // Индекс в массиве
  254.         assert(index < arraySize);          // Отлавливаем переполнение
  255.         const size_t shift = (i % (sizeof(baseType) * 2)) * 4;          // Величина сдвига
  256.  
  257.         parts[index] |= numeral << shift;
  258.     }
  259. }
  260.  
  261. // Преобразование в строку 2-чной системы
  262. template<>
  263. std::string BigUInt192::toString<2>() const
  264. {
  265.     std::stringstream stream;           // Поток, преобразуемый в строку
  266.     bool numberStarted = false;         // Убирает ведущие нули
  267.  
  268.     for (size_t i = 0; i < arraySize; i++) {
  269.         const size_t index = arraySize - i - 1;         // Индекс с конца
  270.         const size_t bits = sizeof(baseType) * 8;       // Количество бит
  271.  
  272.         for (int j = 0; j < bits; j++) {
  273.             const size_t shift = bits - j - 1;          // Величина сдвига
  274.  
  275.             // Цифра (в 2й системе)
  276.             const auto numeral = static_cast<uint16_t>((parts[index] >> shift) & 0b1);
  277.  
  278.             if ((numeral == 0 && numberStarted) || numeral == 1)
  279.                 stream << numeral;
  280.             if (numeral == 1 && !numberStarted)
  281.                 // Каждая следующая цифра (в т.ч. ноль) будет записана
  282.                 numberStarted = true;
  283.         }
  284.     }
  285.  
  286.     // Ничего не было записано => Число 0
  287.     if (!numberStarted)
  288.         return "0";
  289.  
  290.     return stream.str();
  291. }
  292.  
  293. // Преобразование в строку 16-чной системы
  294. // Алгоритм аналогичен шаблону для 2й системы
  295. template<>
  296. std::string BigUInt192::toString<16>() const
  297. {
  298.     std::stringstream stream;
  299.     bool numberStarted = false;
  300.  
  301.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  302.         const size_t index = BigUInt192::arraySize - i - 1;
  303.         const size_t steps = sizeof(BigUInt192::baseType) * 2;
  304.  
  305.         for (int j = 0; j < steps; j++) {
  306.             const size_t shift = (steps - j - 1) * 4;
  307.             const auto numeral = static_cast<uint16_t>((parts[index] >> shift) & 0b1111);
  308.  
  309.             if ((numeral == 0 && numberStarted) || numeral != 0)
  310.                 stream << std::hex << std::uppercase << numeral;
  311.             if (numeral != 0 && !numberStarted)
  312.                 numberStarted = true;
  313.         }
  314.     }
  315.  
  316.     if (!numberStarted)
  317.         return "0";
  318.  
  319.     return stream.str();
  320. }
  321.  
  322. // Алгоритм похож на сложение в столбик
  323. BigUInt192 &operator+=(BigUInt192 &left, const BigUInt192 &right)
  324. {
  325.     // Перенесенный из предыдущего блока бит
  326.     BigUInt192::oversizedType last = 0;
  327.  
  328.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  329.         // Парная сумма + предыдущий бит
  330.         BigUInt192::oversizedType partSum = left.parts[i] + right.parts[i] + last;
  331.  
  332.         if (partSum >> (sizeof(BigUInt192::baseType) * 8) != 0) {
  333.             last = 1;           // Переносим бит из последнего разряда (17й)
  334.         } else {
  335.             last = 0;
  336.         }
  337.  
  338.         // Запоминаем сумму
  339.         left.parts[i] = static_cast<BigUInt192::baseType>(partSum);
  340.     }
  341.  
  342.     assert(last == 0);              // Отлавливаем переполнение
  343.  
  344.     return left;
  345. }
  346.  
  347. BigUInt192 operator+(const BigUInt192 &left, const BigUInt192 &right)
  348. {
  349.     BigUInt192 result(left);        // Копируем константный left
  350.     result += right;                // Применяем +=
  351.     return result;
  352. }
  353.  
  354. // Алгоритм похож на вычитание в столбик
  355. BigUInt192 &operator-=(BigUInt192 &left, const BigUInt192 &right)
  356. {
  357.     // Перенесенный из предыдущего блока бит (необходимо вычесть)
  358.     BigUInt192::oversizedType last = 0;
  359.  
  360.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  361.         // То, что будем вычитать
  362.         const BigUInt192::oversizedType toSub = right.parts[i] + last;
  363.         BigUInt192::oversizedType partSub;  // Результат
  364.  
  365.         if (left.parts[i] >= toSub) {
  366.             partSub = left.parts[i] - toSub;
  367.             last = 0;
  368.         } else {
  369.             // Если правая часть больше левой, "занимаем" бит из следующего блока
  370.             partSub = (1 << 8 * sizeof(BigUInt192::baseType)) + left.parts[i];
  371.             partSub -= toSub;
  372.             last = 1;
  373.         }
  374.  
  375.         // Сохраняем результат
  376.         left.parts[i] = static_cast<BigUInt192::baseType>(partSub);
  377.     }
  378.  
  379.     return left;
  380. }
  381.  
  382. BigUInt192 operator-(const BigUInt192 &left, const BigUInt192 &right)
  383. {
  384.     BigUInt192 result(left);        // Копируем константный left
  385.     result -= right;                // Применяем +=
  386.     return result;
  387. }
  388.  
  389. bool operator>(const BigUInt192 &left, const BigUInt192 &right)
  390. {
  391.     // Сравниваем каждый блок слева направо
  392.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  393.         const size_t index = BigUInt192::arraySize - i - 1;     // Индекс с конца
  394.  
  395.         if (left.parts[index] == right.parts[index])
  396.             continue;
  397.         return left.parts[index] > right.parts[index];
  398.     }
  399.  
  400.     return false;       // Если left == right
  401. }
  402.  
  403. bool operator==(const BigUInt192 &left, const BigUInt192 &right)
  404. {
  405.     // Сравниваем каждый блок слева направо
  406.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  407.         if (left.parts[i] != right.parts[i])
  408.             return false;
  409.     }
  410.     return true;
  411. }
  412.  
  413. /* Следующие 4 операции будут выведены из уже существующих */
  414.  
  415. bool operator!=(const BigUInt192 &left, const BigUInt192 &right)
  416. {
  417.     return !(left == right);
  418. }
  419.  
  420. bool operator<(const BigUInt192 &left, const BigUInt192 &right)
  421. {
  422.     return !(left > right) && left != right;
  423. }
  424.  
  425. bool operator<=(const BigUInt192 &left, const BigUInt192 &right)
  426. {
  427.     return left < right || left == right;
  428. }
  429.  
  430. bool operator>=(const BigUInt192 &left, const BigUInt192 &right)
  431. {
  432.     return left > right || left == right;
  433. }
  434.  
  435. /* Следующие 4 операции будут выведены через метод applyBlock и функтор */
  436.  
  437. BigUInt192 operator&(const BigUInt192 &left, const BigUInt192 &right)
  438. {
  439.     return left.applyBlock(right, std::bit_and<>());
  440. }
  441.  
  442. BigUInt192 operator|(const BigUInt192 &left, const BigUInt192 &right)
  443. {
  444.     return left.applyBlock(right, std::bit_or<>());
  445. }
  446.  
  447. BigUInt192 operator^(const BigUInt192 &left, const BigUInt192 &right)
  448. {
  449.     return left.applyBlock(right, std::bit_xor<>());
  450. }
  451.  
  452. BigUInt192 operator~(const BigUInt192 &left)
  453. {
  454.     return left.applyBlock(std::bit_not<>());
  455. }
  456.  
  457. /* Следующие 2 операции будут выведены через метод shift */
  458.  
  459. BigUInt192 operator<<(const BigUInt192 &left, size_t shift)
  460. {
  461.     return left.shift(0, shift, false);
  462. }
  463.  
  464. BigUInt192 operator>>(const BigUInt192 &left, size_t shift)
  465. {
  466.     return left.shift(1, shift, false);
  467. }
  468.  
  469. // Чтение из потока
  470. std::istream &operator>>(std::istream &istream, BigUInt192 &value)
  471. {
  472.     // Читаем в строку
  473.     std::string input;
  474.     istream >> input;
  475.  
  476.     // Получаем систему счисления
  477.     std::ios_base::fmtflags base = istream.flags() & std::istream::basefield;
  478.  
  479.     switch (base) {
  480.         case std::ios_base::hex: {
  481.             value.fromString<16>(input);
  482.             break;
  483.         }
  484.         default: {
  485.             value.fromString<10>(input);
  486.             break;
  487.         }
  488.     }
  489.  
  490.     return istream;
  491. }
  492.  
  493. std::ostream &operator<<(std::ostream &ostream, const BigUInt192 &value)
  494. {
  495.     // Получаем систему счисления
  496.     std::ios_base::fmtflags base = ostream.flags() & std::istream::basefield;
  497.  
  498.     switch (base) {
  499.         case std::ios_base::hex: {
  500.             ostream << value.toString<16>();
  501.             break;
  502.         }
  503.         default: {
  504.             ostream << value.toString<2>();
  505.             break;
  506.         }
  507.     }
  508.  
  509.     return ostream;
  510. }
  511.  
  512. //** Tester (не будет вставлен в отчет) //
  513.  
  514. #define TESTER
  515. #define BOOL_TO_STRING(x) ((x) ? "Correct" : "Wrong")
  516.  
  517. // Функция для тестирования корректной работы перегруженных операций
  518. void tester()
  519. {
  520.     using keyType = std::pair<std::string, std::string>;
  521.     using valueType = std::vector<std::string>;
  522.  
  523.     std::map<keyType, valueType> tests = {
  524.         {
  525.             {
  526.                 "FF",
  527.                 "AA"
  528.             },
  529.             {
  530.                 "1A9",                                              // +
  531.                 "55",                                               // -
  532.                 "1FE0",                                             // << 5
  533.                 "F80000000000000000000000000000000000000000000007", // circle >> 5
  534.                 "AA",                                               // &
  535.                 "FF",                                               // |
  536.                 "55",                                               // ^
  537.                 "1",                                                // >
  538.                 "1",                                                // !=
  539.             }
  540.         },
  541.         {
  542.             {
  543.                 "AA5F601",
  544.                 "8D9A34"
  545.             },
  546.             {
  547.                 "B339035",                                          // +
  548.                 "A185BCD",                                          // -
  549.                 "154BEC020",                                        // << 5
  550.                 "80000000000000000000000000000000000000000552FB0",  // circle >> 5
  551.                 "859200",                                           // &
  552.                 "AADFE35",                                          // |
  553.                 "A286C35",                                          // ^
  554.                 "1",                                                // >
  555.                 "1",                                                // !=
  556.             }
  557.         },
  558.         {
  559.             {
  560.                 "135",
  561.                 "135"
  562.             },
  563.             {
  564.                 "26A",                                              // +
  565.                 "0",                                                // -
  566.                 "26A0",                                             // << 5
  567.                 "A80000000000000000000000000000000000000000000009", // circle >> 5
  568.                 "135",                                              // &
  569.                 "135",                                              // |
  570.                 "0",                                                // ^
  571.                 "0",                                                // >
  572.                 "0",                                                // !=
  573.             }
  574.         },
  575.     };
  576.  
  577.     // Проверка
  578.     for (const auto &it : tests) {
  579.         BigUInt192 left;
  580.         left.fromString<16>(it.first.first);
  581.         BigUInt192 right;
  582.         right.fromString<16>(it.first.second);
  583.         std::cout << "A = " << std::hex << left << std::endl;
  584.         std::cout << "B = " << std::hex << right << std::endl;
  585.  
  586.         const valueType &results = it.second;
  587.         BigUInt192 tempResult;
  588.         tempResult.fromString<16>(results[0]);
  589.         std::cout << "A + B   " << BOOL_TO_STRING((left + right) == tempResult) << std::endl;
  590.         tempResult.fromString<16>(results[1]);
  591.         std::cout << "A - B   " << BOOL_TO_STRING((left - right) == tempResult) << std::endl;
  592.         tempResult.fromString<16>(results[2]);
  593.         std::cout << "A << 5  " << BOOL_TO_STRING((left << 5) == tempResult) << std::endl;
  594.         tempResult.fromString<16>(results[3]);
  595.         std::cout << "A c>> 5 " << BOOL_TO_STRING(left.shiftCircleR(5) == tempResult) << std::endl;
  596.         tempResult.fromString<16>(results[4]);
  597.         std::cout << "A & B   " << BOOL_TO_STRING((left & right) == tempResult) << std::endl;
  598.         tempResult.fromString<16>(results[5]);
  599.         std::cout << "A | B   " << BOOL_TO_STRING((left | right) == tempResult) << std::endl;
  600.         tempResult.fromString<16>(results[6]);
  601.         std::cout << "A ^ B   " << BOOL_TO_STRING((left ^ right) == tempResult) << std::endl;
  602.         std::cout << "A > B   " << BOOL_TO_STRING((left > right) == (results[7] == "1")) << std::endl;
  603.         std::cout << "A != B  " << BOOL_TO_STRING((left != right) == (results[8] == "1")) << std::endl;
  604.     }
  605. }
  606.  
  607. // Tester **//
  608.  
  609. int main()
  610. {
  611.  
  612. #ifdef TESTER
  613.     tester();
  614. #endif
  615.  
  616.     // Ввод типов
  617.     size_t inputType;       // Тип ввода
  618.     size_t outputType;      // Тип вывода
  619.     std::cout << "Choose input type ( HEX(0) or DEC(1) ): ";
  620.     std::cin >> inputType;
  621.     std::cout << "Choose output type ( HEX(0) or BIN(1) ): ";
  622.     std::cin >> outputType;
  623.  
  624.     // Ввод больших чисел и размера сдвига
  625.     BigUInt192 left;
  626.     BigUInt192 right;
  627.     size_t shiftSize;
  628.     std::cout << "A = ";
  629.     std::cin >> ((inputType == 1) ? std::dec : std::hex) >> left;
  630.     std::cout << "B = ";
  631.     std::cin >> ((inputType == 1) ? std::dec : std::hex) >> right;
  632.     std::cout << "Enter shift size (DEC): ";
  633.     std::cin >> shiftSize;
  634.  
  635.     // Вывод результатов операций над данными числами
  636.     auto flag = ((outputType == 0) ? std::hex : std::dec);
  637.     std::cout << "A       = " << left << std::endl;
  638.     std::cout << "B       = " << right << std::endl;
  639.     std::cout << "A + B   = " << flag << (left + right) << std::endl;
  640.     std::cout << "A - B   = " << flag << (left - right) << std::endl;
  641.     std::cout << "A << s  = " << flag << (left << shiftSize) << std::endl;
  642.     std::cout << "A >> s  = " << flag << (left >> shiftSize) << std::endl;
  643.     std::cout << "A c<< s = " << flag << left.shiftCircleL(shiftSize) << std::endl;
  644.     std::cout << "A c>> s = " << flag << left.shiftCircleR(shiftSize) << std::endl;
  645.     std::cout << "A & B   = " << flag << (left & right) << std::endl;
  646.     std::cout << "A | B   = " << flag << (left | right) << std::endl;
  647.     std::cout << "A ^ B   = " << flag << (left ^ right) << std::endl;
  648.     std::cout << "A > B   = " << flag << (left > right) << std::endl;
  649.     std::cout << "A < B   = " << flag << (left < right) << std::endl;
  650.     std::cout << "A == B  = " << flag << (left == right) << std::endl;
  651.  
  652.     return 0;
  653. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement