Toliak

lab8_1

Nov 27th, 2018
406
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 8.25 KB | None | 0 0
  1. #include <iostream>
  2. #include <cstring>
  3. #include <vector>
  4. #include <cassert>
  5. #include <functional>
  6.  
  7. #define MAX(x, y) ((x) > (y) ? (x) : (y))
  8.  
  9. struct BigUInt192
  10. {
  11.     using baseType = uint16_t;
  12.     using oversizedType = uint32_t;
  13.  
  14.     BigUInt192()
  15.     {
  16.         parts = new baseType[arraySize];
  17.         this->erase();
  18.     }
  19.     BigUInt192(const BigUInt192 &original): BigUInt192()
  20.     {
  21.         std::memcpy(parts, original.parts, sizeof(baseType) * arraySize);
  22.     }
  23.     void erase()
  24.     {
  25.         std::memset(parts, 0, sizeof(baseType) * arraySize);
  26.     }
  27.     template<template <class> class F, class T>
  28.     BigUInt192 applyBlock(F<T> functor) const
  29.     {
  30.         BigUInt192 result;
  31.         for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  32.             result.parts[i] = functor(parts[i]);
  33.         }
  34.         return result;
  35.     }
  36.     template<template <class> class F, class T>
  37.     BigUInt192 applyBlock(const BigUInt192 &right, F<T> functor) const
  38.     {
  39.         BigUInt192 result;
  40.         for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  41.             result.parts[i] = functor(parts[i], right.parts[i]);
  42.         }
  43.         return result;
  44.     }
  45.  
  46.     ~BigUInt192()
  47.     {
  48.         delete[] parts;
  49.     }
  50.  
  51.     static const size_t bytes = 24;
  52.     static const size_t arraySize = bytes / sizeof(baseType) + (bytes % sizeof(baseType) > 0);
  53.  
  54.     baseType *parts;
  55. };
  56.  
  57. BigUInt192 operator+(const BigUInt192 &left, const BigUInt192 &right)
  58. {
  59.     BigUInt192 result;
  60.     BigUInt192::oversizedType last = 0;
  61.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  62.         BigUInt192::oversizedType partSum = left.parts[i] + right.parts[i] + last;
  63.         if (partSum >> 16 != 0) {
  64.             last = 1;           // Переносим бит из последнего разряда (17й)
  65.         } else {
  66.             last = 0;
  67.         }
  68.         result.parts[i] = static_cast<BigUInt192::baseType>(partSum);
  69.     }
  70.     return result;
  71. }
  72.  
  73. BigUInt192 operator-(const BigUInt192 &left, const BigUInt192 &right)
  74. {
  75.     BigUInt192 result;
  76.     bool last = false;
  77.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  78.         const BigUInt192::oversizedType toSub = right.parts[i] + last;
  79.         BigUInt192::oversizedType partSub;
  80.         if (left.parts[i] >= toSub) {
  81.             partSub = left.parts[i] - toSub;
  82.             last = false;
  83.         } else {
  84.             partSub = (1 << 8 * sizeof(BigUInt192::baseType)) + left.parts[i];
  85.             partSub -= right.parts[i];
  86.             last = true;
  87.         }
  88.         result.parts[i] = static_cast<BigUInt192::baseType>(partSub);
  89.     }
  90.     return result;
  91. }
  92.  
  93. bool operator>(const BigUInt192 &left, const BigUInt192 &right)
  94. {
  95.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  96.         const size_t index = BigUInt192::arraySize - i - 1;
  97.         if (left.parts[index] == right.parts[index])
  98.             continue;
  99.         return left.parts[index] > right.parts[index];
  100.     }
  101.     return false;
  102. }
  103.  
  104. bool operator==(const BigUInt192 &left, const BigUInt192 &right)
  105. {
  106.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  107.         if (left.parts[i] != right.parts[i])
  108.             return false;
  109.     }
  110.     return true;
  111. }
  112.  
  113. bool operator!=(const BigUInt192 &left, const BigUInt192 &right)
  114. {
  115.     return !(left == right);
  116. }
  117.  
  118. bool operator<(const BigUInt192 &left, const BigUInt192 &right)
  119. {
  120.     return !(left > right) && left != right;
  121. }
  122.  
  123. bool operator<=(const BigUInt192 &left, const BigUInt192 &right)
  124. {
  125.     return left < right || left == right;
  126. }
  127.  
  128. bool operator>=(const BigUInt192 &left, const BigUInt192 &right)
  129. {
  130.     return left > right || left == right;
  131. }
  132.  
  133. BigUInt192 operator&(const BigUInt192 &left, const BigUInt192 &right)
  134. {
  135.     return left.applyBlock(right, std::bit_and<>());
  136. }
  137.  
  138. BigUInt192 operator|(const BigUInt192 &left, const BigUInt192 &right)
  139. {
  140.     return left.applyBlock(right, std::bit_or<>());
  141. }
  142.  
  143. BigUInt192 operator^(const BigUInt192 &left, const BigUInt192 &right)
  144. {
  145.     return left.applyBlock(right, std::bit_xor<>());
  146. }
  147.  
  148. BigUInt192 operator~(const BigUInt192 &left)
  149. {
  150.     return left.applyBlock(std::bit_not<>());
  151. }
  152.  
  153. BigUInt192 operator<<(const BigUInt192 &left, size_t shift)
  154. {
  155.     BigUInt192::baseType mask = 0x0;
  156.     for (size_t i = 0; i < shift; i++) {
  157.         mask = static_cast<BigUInt192::baseType>(mask << 1 | 1);
  158.     }
  159.  
  160.     BigUInt192 result;
  161.     BigUInt192::baseType last = 0;
  162.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  163.         result.parts[i] = (left.parts[i] << shift) | last;
  164.         last = (left.parts[i] >> (8 * sizeof(BigUInt192::baseType) - shift)) & mask;
  165.     }
  166.     return result;
  167. }
  168.  
  169. BigUInt192 operator>>(const BigUInt192 &left, size_t shift)
  170. {
  171.     BigUInt192::baseType mask = 0x0;
  172.     for (size_t i = 0; i < shift; i++) {
  173.         mask = static_cast<BigUInt192::baseType>(mask << 1 | 1);
  174.     }
  175.  
  176.     BigUInt192 result;
  177.     BigUInt192::baseType last = 0;
  178.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  179.         const size_t index = BigUInt192::arraySize - i - 1;
  180.         result.parts[index] = (left.parts[index] >> shift);
  181.         result.parts[index] |= last << (8 * sizeof(BigUInt192::baseType) - shift);
  182.         last = left.parts[index] & mask;
  183.     }
  184.     return result;
  185. }
  186.  
  187. BigUInt192 circledShiftL(const BigUInt192 &left, size_t shift)
  188. {
  189.     BigUInt192::baseType mask = 0x0;
  190.     for (size_t i = 0; i < shift; i++) {
  191.         mask = static_cast<BigUInt192::baseType>(mask << 1 | 1);
  192.     }
  193.  
  194.     BigUInt192 result;
  195.     BigUInt192::baseType last = 0;
  196.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  197.         result.parts[i] = (left.parts[i] << shift) | last;
  198.         last = (left.parts[i] >> (8 * sizeof(BigUInt192::baseType) - shift)) & mask;
  199.     }
  200.     result.parts[0] |= last;
  201.     return result;
  202. }
  203.  
  204. BigUInt192 circledShiftR(const BigUInt192 &left, size_t shift)
  205. {
  206.     BigUInt192::baseType mask = 0x0;
  207.     for (size_t i = 0; i < shift; i++) {
  208.         mask = static_cast<BigUInt192::baseType>(mask << 1 | 1);
  209.     }
  210.  
  211.     BigUInt192 result;
  212.     BigUInt192::baseType last = 0;
  213.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  214.         const size_t index = BigUInt192::arraySize - i - 1;
  215.         result.parts[index] = (left.parts[index] >> shift);
  216.         result.parts[index] |= last << (8 * sizeof(BigUInt192::baseType) - shift);
  217.         last = left.parts[index] & mask;
  218.     }
  219.     result.parts[BigUInt192::arraySize - 1] |= last << (8 * sizeof(BigUInt192::baseType) - shift);
  220.     return result;
  221. }
  222.  
  223. std::istream &operator>>(std::istream &istream, BigUInt192 &value)
  224. {
  225.     std::string s;
  226.     istream >> s;
  227.     value.erase();
  228.  
  229.     for (auto it = s.crbegin(); it != s.crend(); it++) {
  230.         const size_t i = static_cast<size_t>(it - s.crbegin());
  231.         assert(*it == '0' || *it == '1');
  232.         if (*it == '0')
  233.             continue;
  234.  
  235.         const size_t index = i / (sizeof(BigUInt192::baseType) * 8);
  236.         const size_t shift = i % (sizeof(BigUInt192::baseType) * 8);
  237.         value.parts[index] |= (*it - '0') << shift;
  238.     }
  239.  
  240.     return istream;
  241. }
  242.  
  243. std::ostream &operator<<(std::ostream &ostream, const BigUInt192 &value)
  244. {
  245.     bool numberStarted = false;
  246.     for (size_t i = 0; i < BigUInt192::arraySize; i++) {
  247.         const size_t index = BigUInt192::arraySize - i - 1;
  248.         const size_t bits = sizeof(BigUInt192::baseType) * 8;
  249.         for (int j = 0; j < bits; j++) {
  250.             const size_t shift = bits - j - 1;
  251.             auto numeral = (value.parts[index] >> shift) & 0x1;
  252.             if ((numeral == 0 && numberStarted) || numeral == 1)
  253.                 ostream << numeral;
  254.             if (numeral == 1 && !numberStarted)
  255.                 numberStarted = true;
  256.         }
  257.     }
  258.  
  259.     return ostream;
  260. }
  261.  
  262. int main()
  263. {
  264.  
  265.     BigUInt192 b;
  266.  
  267.     std::cout << (uint16_t) (12 - 32) << std::endl;
  268.  
  269.     BigUInt192 v;
  270.     //std::cout << "Enter BIN big value: ";
  271.     std::cin >> v;
  272.     std::cin >> b;
  273.     std::cout << circledShiftR(v, 5) << std::endl;
  274.     std::cout << circledShiftL(v, 5) << std::endl;
  275.     std::cout << v + b << std::endl;
  276.     std::cout << v - b << std::endl;
  277.     std::cout << (v & b) << std::endl;
  278.     std::cout << (v | b) << std::endl;
  279.     std::cout << (v > b) << std::endl;
  280.     std::cout << "Hello, World!" << std::endl;
  281.     return 0;
  282. }
Advertisement
Add Comment
Please, Sign In to add comment