Advertisement
Toliak

lab8_2

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