Advertisement
Toliak

lab8_4

Nov 28th, 2018
363
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 12.23 KB | None | 0 0
  1. #include <iostream>
  2. #include <iomanip>
  3. #include <cstring>
  4. #include <vector>
  5. #include <cassert>
  6. #include <unordered_map>
  7. #include <functional>
  8.  
  9. struct BigUInt192
  10. {
  11.     using baseType = uint16_t;
  12.     using oversizedType = uint32_t;
  13.  
  14.     static_assert(sizeof(baseType) < sizeof(oversizedType), "");
  15.  
  16.     BigUInt192()
  17.     {
  18.         parts = new baseType[arraySize];
  19.         this->erase();
  20.     }
  21.     BigUInt192(const BigUInt192 &original)
  22.         : BigUInt192()
  23.     {
  24.         std::memcpy(parts, original.parts, sizeof(baseType) * arraySize);
  25.     }
  26.     BigUInt192(const baseType& original) : BigUInt192()
  27.     {
  28.  
  29.     }
  30.     template<int T>
  31.     void fromString(const std::string &str)
  32.     {
  33.         // something went wrong
  34.     }
  35.     void erase()
  36.     {
  37.         std::memset(parts, 0, sizeof(baseType) * arraySize);
  38.     }
  39.     template<template<class> class F, class T>
  40.     BigUInt192 applyBlock(F<T> functor) const
  41.     {
  42.         BigUInt192 result;
  43.         for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  44.             result.parts[i] = functor(parts[i]);
  45.         }
  46.         return result;
  47.     }
  48.     template<template<class> class F, class T>
  49.     BigUInt192 applyBlock(const BigUInt192 &right, F<T> functor) const
  50.     {
  51.         BigUInt192 result;
  52.         for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  53.             result.parts[i] = functor(parts[i], right.parts[i]);
  54.         }
  55.         return result;
  56.     }
  57.     BigUInt192 shift(char way, size_t amount, bool circled) const
  58.     {
  59.         BigUInt192::baseType mask = 0x0;
  60.         for (size_t i = 0; i < amount; i++) {
  61.             mask = static_cast<BigUInt192::baseType>(mask << 1 | 1);
  62.         }
  63.  
  64.         BigUInt192 result;
  65.         BigUInt192::baseType last = 0;
  66.         if (way == 0) {                     // <<
  67.             for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  68.                 result.parts[i] = (parts[i] << amount) | last;
  69.                 last = (parts[i] >> (8 * sizeof(BigUInt192::baseType) - amount)) & mask;
  70.             }
  71.         } else {                            // >>
  72.             for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  73.                 const size_t index = BigUInt192::arraySize - i - 1;
  74.                 result.parts[index] = (parts[index] >> amount);
  75.                 result.parts[index] |= last << (8 * sizeof(BigUInt192::baseType) - amount);
  76.                 last = parts[index] & mask;
  77.             }
  78.         }
  79.  
  80.         if (circled) {
  81.             if (way == 0)                   // <<
  82.                 result.parts[0] |= last;
  83.             else                            // >>
  84.                 result.parts[BigUInt192::arraySize - 1] |= last << (8 * sizeof(BigUInt192::baseType) - amount);
  85.         }
  86.  
  87.         return result;
  88.     }
  89.     BigUInt192 shiftCircleL(size_t amount)
  90.     {
  91.         return shift(0, amount, true);
  92.     }
  93.     BigUInt192 shiftCircleR(size_t amount)
  94.     {
  95.         return shift(1, amount, true);
  96.     }
  97.  
  98.     friend BigUInt192& operator+=(BigUInt192&, const BigUInt192&);
  99.     friend BigUInt192 operator+(const BigUInt192&, const BigUInt192&);
  100.     friend BigUInt192 operator-(const BigUInt192&, const BigUInt192&);
  101.     friend bool operator>(const BigUInt192&, const BigUInt192&);
  102.     friend bool operator==(const BigUInt192&, const BigUInt192&);
  103.     friend bool operator!=(const BigUInt192&, const BigUInt192&);
  104.     friend bool operator<(const BigUInt192&, const BigUInt192&);
  105.     friend bool operator<=(const BigUInt192&, const BigUInt192&);
  106.     friend bool operator>=(const BigUInt192&, const BigUInt192&);
  107.     friend BigUInt192 operator&(const BigUInt192&, const BigUInt192&);
  108.     friend BigUInt192 operator|(const BigUInt192&, const BigUInt192&);
  109.     friend BigUInt192 operator^(const BigUInt192&, const BigUInt192&);
  110.     friend BigUInt192 operator~(const BigUInt192&);
  111.     friend BigUInt192 operator<<(const BigUInt192&, size_t);
  112.     friend BigUInt192 operator>>(const BigUInt192&, size_t);
  113.     friend std::istream& operator>>(std::istream&, BigUInt192&);
  114.     friend std::ostream& operator<<(std::ostream&, const BigUInt192&);
  115.  
  116.     BigUInt192& multiplySlow(const BigUInt192& right)
  117.     {
  118.         BigUInt192 original(*this);
  119.         for (BigUInt192 i; i < right; i += 1) {
  120.             *this += original;
  121.         }
  122.         return *this;
  123.     }
  124.     BigUInt192& divideSlow(const BigUInt192& BigUInt192)
  125.     {
  126.         BigUInt192 result;
  127.         while()
  128.         return *this;
  129.     }
  130.  
  131.  
  132.     template<int T>
  133.     std::string toString() const
  134.     {
  135.         assert(false);
  136.     }
  137.  
  138.     ~BigUInt192()
  139.     {
  140.         delete[] parts;
  141.     }
  142.  
  143.     static const size_t bytes = 24;
  144.     static const size_t arraySize = bytes / sizeof(baseType) + (bytes % sizeof(baseType) > 0);
  145.  
  146.     baseType *parts;
  147. };
  148.  
  149. template<>
  150. void BigUInt192::fromString<2>(const std::string &str)
  151. {
  152.     erase();
  153.     for (auto it = str.crbegin(); it != str.crend(); it++) {
  154.         const size_t i = static_cast<size_t>(it - str.crbegin());
  155.         assert(*it == '0' || *it == '1');
  156.         if (*it == '0')
  157.             continue;
  158.  
  159.         const size_t index = i / (sizeof(BigUInt192::baseType) * 8);
  160.         const size_t shift = i % (sizeof(BigUInt192::baseType) * 8);
  161.         parts[index] |= (*it - '0') << shift;
  162.     }
  163. }
  164.  
  165. template<>
  166. void BigUInt192::fromString<16>(const std::string &str)
  167. {
  168.     erase();
  169.     for (auto it = str.crbegin(); it != str.crend(); it++) {
  170.         if (*it == '0')
  171.             continue;
  172.  
  173.         const size_t i = static_cast<size_t>(it - str.crbegin());
  174.         BigUInt192::baseType numeral;
  175.         std::stringstream stream;
  176.         stream << std::nouppercase << *it;
  177.         stream >> std::hex >> numeral;
  178.  
  179.         const size_t index = i / (sizeof(BigUInt192::baseType) * 8);
  180.         const size_t shift = (i % (sizeof(BigUInt192::baseType) * 2)) * 4;
  181.         parts[index] |= numeral << shift;
  182.     }
  183. }
  184.  
  185. template<>
  186. std::string BigUInt192::toString<2>() const
  187. {
  188.     std::stringstream stream;
  189.     bool numberStarted = false;
  190.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  191.         const size_t index = BigUInt192::arraySize - i - 1;
  192.         const size_t bits = sizeof(BigUInt192::baseType) * 8;
  193.         for (int j = 0; j < bits; j++) {
  194.             const size_t shift = bits - j - 1;
  195.             const auto numeral = static_cast<uint16_t>((parts[index] >> shift) & 0b1);
  196.             if ((numeral == 0 && numberStarted) || numeral == 1)
  197.                 stream << numeral;
  198.             if (numeral == 1 && !numberStarted)
  199.                 numberStarted = true;
  200.         }
  201.     }
  202.     return stream.str();
  203. }
  204.  
  205. template<>
  206. std::string BigUInt192::toString<16>() const
  207. {
  208.     std::stringstream stream;
  209.     bool numberStarted = false;
  210.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  211.         const size_t index = BigUInt192::arraySize - i - 1;
  212.         const size_t steps = sizeof(BigUInt192::baseType) * 2;
  213.         for (int j = 0; j < steps; j++) {
  214.             const size_t shift = (steps - j - 1) * 4;
  215.             const auto numeral = static_cast<uint16_t>((parts[index] >> shift) & 0b1111);
  216.             if ((numeral == 0 && numberStarted) || numeral != 0)
  217.                 stream << std::hex << std::uppercase << numeral;
  218.             if (numeral != 0 && !numberStarted)
  219.                 numberStarted = true;
  220.         }
  221.     }
  222.     return stream.str();
  223. }
  224.  
  225. BigUInt192& operator+=(BigUInt192 &left, const BigUInt192 &right)
  226. {
  227.     BigUInt192::oversizedType last = 0;
  228.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  229.         BigUInt192::oversizedType partSum = left.parts[i] + right.parts[i] + last;
  230.         if (partSum >> 16 != 0) {
  231.             last = 1;           // Переносим бит из последнего разряда (17й)
  232.         } else {
  233.             last = 0;
  234.         }
  235.         left.parts[i] = static_cast<BigUInt192::baseType>(partSum);
  236.     }
  237.     return left;
  238. }
  239.  
  240. const BigUInt192 operator+(const BigUInt192 &left, const BigUInt192 &right)
  241. {
  242.     BigUInt192 result(left);
  243.     result += right;
  244.     return result;
  245. }
  246.  
  247. BigUInt192 operator-(const BigUInt192 &left, const BigUInt192 &right)
  248. {
  249.     BigUInt192 result;
  250.     bool last = false;
  251.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  252.         const BigUInt192::oversizedType toSub = right.parts[i] + last;
  253.         BigUInt192::oversizedType partSub;
  254.         if (left.parts[i] >= toSub) {
  255.             partSub = left.parts[i] - toSub;
  256.             last = false;
  257.         } else {
  258.             partSub = (1 << 8 * sizeof(BigUInt192::baseType)) + left.parts[i];
  259.             partSub -= right.parts[i];
  260.             last = true;
  261.         }
  262.         result.parts[i] = static_cast<BigUInt192::baseType>(partSub);
  263.     }
  264.     return result;
  265. }
  266.  
  267. bool operator>(const BigUInt192 &left, const BigUInt192 &right)
  268. {
  269.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  270.         const size_t index = BigUInt192::arraySize - i - 1;
  271.         if (left.parts[index] == right.parts[index])
  272.             continue;
  273.         return left.parts[index] > right.parts[index];
  274.     }
  275.     return false;
  276. }
  277.  
  278. bool operator==(const BigUInt192 &left, const BigUInt192 &right)
  279. {
  280.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  281.         if (left.parts[i] != right.parts[i])
  282.             return false;
  283.     }
  284.     return true;
  285. }
  286.  
  287. bool operator!=(const BigUInt192 &left, const BigUInt192 &right)
  288. {
  289.     return !(left == right);
  290. }
  291.  
  292. bool operator<(const BigUInt192 &left, const BigUInt192 &right)
  293. {
  294.     return !(left > right) && left != right;
  295. }
  296.  
  297. bool operator<=(const BigUInt192 &left, const BigUInt192 &right)
  298. {
  299.     return left < right || left == right;
  300. }
  301.  
  302. bool operator>=(const BigUInt192 &left, const BigUInt192 &right)
  303. {
  304.     return left > right || left == right;
  305. }
  306.  
  307. BigUInt192 operator&(const BigUInt192 &left, const BigUInt192 &right)
  308. {
  309.     return left.applyBlock(right, std::bit_and<>());
  310. }
  311.  
  312. BigUInt192 operator|(const BigUInt192 &left, const BigUInt192 &right)
  313. {
  314.     return left.applyBlock(right, std::bit_or<>());
  315. }
  316.  
  317. BigUInt192 operator^(const BigUInt192 &left, const BigUInt192 &right)
  318. {
  319.     return left.applyBlock(right, std::bit_xor<>());
  320. }
  321.  
  322. BigUInt192 operator~(const BigUInt192 &left)
  323. {
  324.     return left.applyBlock(std::bit_not<>());
  325. }
  326.  
  327. BigUInt192 operator<<(const BigUInt192 &left, size_t shift)
  328. {
  329.     return left.shift(0, shift, false);
  330. }
  331.  
  332. BigUInt192 operator>>(const BigUInt192 &left, size_t shift)
  333. {
  334.     return left.shift(1, shift, false);
  335. }
  336.  
  337. std::istream &operator>>(std::istream &istream, BigUInt192 &value)
  338. {
  339.  
  340.     std::string s;
  341.     istream >> s;
  342.  
  343.     std::ios_base::fmtflags base = istream.flags() & std::istream::basefield;
  344.     switch (base) {
  345.         case std::ios_base::dec: {
  346.             value.fromString<2>(s);
  347.             break;
  348.         }
  349.         case std::ios_base::hex: {
  350.             value.fromString<16>(s);
  351.             break;
  352.         }
  353.         default: {
  354.             value.fromString<2>(s);
  355.             break;
  356.         }
  357.     }
  358.  
  359.     return istream;
  360. }
  361.  
  362. std::ostream &operator<<(std::ostream &ostream, const BigUInt192 &value)
  363. {
  364.     auto temp = ostream.flags();
  365.  
  366.     std::ios_base::fmtflags base = ostream.flags() & std::istream::basefield;
  367.     switch (base) {
  368.         case std::ios_base::dec: {
  369.             ostream << value.toString<2>();
  370.             break;
  371.         }
  372.         case std::ios_base::hex: {
  373.             ostream << value.toString<16>();
  374.             break;
  375.         }
  376.         default: {
  377.             ostream << value.toString<2>();
  378.             break;
  379.         }
  380.     }
  381.  
  382.     return ostream;
  383. }
  384.  
  385. int main()
  386. {
  387.  
  388.     BigUInt192 test1L;
  389.     BigUInt192 test1R;
  390.     test1L.fromString<16>("FF");
  391.     test1R.fromString<16>("AA");
  392.     BigUInt192 test1Result1;
  393.     // test1Result1.fromString("")
  394.     // std::cout << BigUInt192("FF") +  << std::endl;
  395.  
  396.     BigUInt192 a;
  397.     BigUInt192 b;
  398.  
  399.     std::cin >> std::hex >> a;
  400.     std::cin >> std::hex >> b;
  401.  
  402.     std::cout << std::hex << circledShiftR(a, 5) << std::endl;
  403.     std::cout << std::hex << circledShiftL(b, 5) << std::endl;
  404.     std::cout << std::hex << a + b << std::endl;
  405.     std::cout << std::hex << a - b << std::endl;
  406.     std::cout << std::hex << (a & b) << std::endl;
  407.     std::cout << std::hex << (a | b) << std::endl;
  408.     std::cout << std::hex << (a > b) << std::endl;
  409.  
  410.     std::cout << "Hello, World!" << std::endl;
  411.     return 0;
  412. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement