Guest User

Untitled

a guest
Mar 9th, 2013
143
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 14.26 KB | None | 0 0
  1. #include <vector>
  2. #include <string>
  3. #include <ostream>
  4. #include <iomanip>
  5. #include <sstream>
  6.  
  7. class big_integer {
  8.     // основание системы счисления (1 000 000 000)
  9.     static const int BASE = 1000000000;
  10.  
  11.     // внутреннее хранилище числа
  12.     std::vector<int> _digits;
  13.  
  14.     // знак числа
  15.     bool _is_negative;
  16.  
  17.     void _remove_leading_zeros();
  18.     void _shift_right();
  19.  
  20. public:
  21.     // класс-исключение, бросаемое при делении на ноль
  22.     class divide_by_zero {  };
  23.  
  24.     big_integer();
  25.     big_integer(std::string);
  26.     big_integer(signed char);
  27.     big_integer(unsigned char);
  28.     big_integer(signed short);
  29.     big_integer(unsigned short);
  30.     big_integer(signed int);
  31.     big_integer(unsigned int);
  32.     big_integer(signed long);
  33.     big_integer(unsigned long);
  34.     big_integer(signed long long);
  35.     big_integer(unsigned long long);
  36.  
  37.     friend std::ostream& operator <<(std::ostream&, const big_integer&);
  38.     operator std::string() const;
  39.     const big_integer operator +() const;
  40.     const big_integer operator -() const;
  41.     const big_integer operator ++();
  42.     const big_integer operator ++(int);
  43.     const big_integer operator --();
  44.     const big_integer operator --(int);
  45.     friend bool operator ==(const big_integer&, const big_integer&);
  46.     friend bool operator <(const big_integer&, const big_integer&);
  47.     friend bool operator !=(const big_integer&, const big_integer&);
  48.     friend bool operator <=(const big_integer&, const big_integer&);
  49.     friend bool operator >(const big_integer&, const big_integer&);
  50.     friend bool operator >=(const big_integer&, const big_integer&);
  51.     friend const big_integer operator +(big_integer, const big_integer&);
  52.     big_integer& operator +=(const big_integer&);
  53.     friend const big_integer operator -(big_integer, const big_integer&);
  54.     big_integer& operator -=(const big_integer&);
  55.     friend const big_integer operator *(const big_integer&, const big_integer&);
  56.     big_integer& operator *=(const big_integer&);
  57.     friend const big_integer operator /(const big_integer&, const big_integer&);
  58.     big_integer& operator /=(const big_integer&);
  59.     friend const big_integer operator %(const big_integer&, const big_integer&);
  60.     big_integer& operator %=(const big_integer&);
  61.  
  62.     bool odd() const;
  63.     bool even() const;
  64.     const big_integer pow(big_integer) const;
  65. };
  66.  
  67. // создает длинное целое число со значением 0
  68. big_integer::big_integer() {
  69.     this->_is_negative = false;
  70. }
  71.  
  72. // создает длинное целое число из C++-строки
  73. big_integer::big_integer(std::string str) {
  74.     if (str.length() == 0) {
  75.         this->_is_negative = false;
  76.     }
  77.     else {
  78.         if (str[0] == '-') {
  79.             str = str.substr(1);
  80.             this->_is_negative = true;
  81.         }
  82.         else {
  83.             this->_is_negative = false;
  84.         }
  85.  
  86.         for (long long i = str.length(); i > 0; i -= 9) {
  87.             if (i < 9)
  88.                 this->_digits.push_back(atoi(str.substr(0, i).c_str()));
  89.             else
  90.                 this->_digits.push_back(atoi(str.substr(i - 9, 9).c_str()));
  91.         }
  92.  
  93.         this->_remove_leading_zeros();
  94.     }
  95. }
  96.  
  97. // удаляет ведущие нули
  98. void big_integer::_remove_leading_zeros() {
  99.     while (this->_digits.size() > 1 && this->_digits.back() == 0) {
  100.         this->_digits.pop_back();
  101.     }
  102.  
  103.     if (this->_digits.size() == 1 && this->_digits[0] == 0) this->_is_negative = false;
  104. }
  105.  
  106. // печатает число в поток вывода
  107. std::ostream& operator <<(std::ostream& os, const big_integer& bi) {
  108.     if (bi._digits.empty()) os << 0;
  109.     else {
  110.         if (bi._is_negative) os << '-';
  111.         os << bi._digits.back();
  112.         char old_fill = os.fill('0');
  113.         for (long long i = static_cast<long long>(bi._digits.size()) - 2; i >= 0; --i) os << std::setw(9) << bi._digits[i];
  114.         os.fill(old_fill);
  115.     }
  116.  
  117.     return os;
  118. }
  119.  
  120. // сравнивает два числа на равенство
  121. bool operator ==(const big_integer& left, const big_integer& right) {
  122.     if (left._is_negative != right._is_negative) return false;
  123.     if (left._digits.empty()) {
  124.         if (right._digits.empty() || (right._digits.size() == 1 && right._digits[0] == 0)) return true;
  125.         else return false;
  126.     }
  127.    
  128.     if (right._digits.empty()) {
  129.         if (left._digits.size() == 1 && left._digits[0] == 0) return true;
  130.         else return false;
  131.     }
  132.  
  133.     if (left._digits.size() != right._digits.size()) return false;
  134.     for (size_t i = 0; i < left._digits.size(); ++i) if (left._digits[i] != right._digits[i]) return false;
  135.  
  136.     return true;
  137. }
  138.  
  139. // возвращает копию переданного числа
  140. const big_integer big_integer::operator +() const {
  141.     return big_integer(*this);
  142. }
  143.  
  144. // возвращает переданное число с другим знаком
  145. const big_integer big_integer::operator -() const {
  146.     big_integer copy(*this);
  147.     copy._is_negative = !copy._is_negative;
  148.     return copy;
  149. }
  150.  
  151. // проверяет, является ли левый операнд меньше правого
  152. bool operator <(const big_integer& left, const big_integer& right) {
  153.     if (left == right) return false;
  154.     if (left._is_negative) {
  155.         if (right._is_negative) return ((-right) < (-left));
  156.         else return true;
  157.     }
  158.     else if (right._is_negative) return false;
  159.     else {
  160.         if (left._digits.size() != right._digits.size()) {
  161.             return left._digits.size() < right._digits.size();
  162.         }
  163.         else {
  164.             for (long long i = left._digits.size() - 1; i >= 0; --i) {
  165.                 if (left._digits[i] != right._digits[i]) return left._digits[i] < right._digits[i];
  166.             }
  167.            
  168.             return false;
  169.         }
  170.     }
  171. }
  172.  
  173. // сравнивает два числа на неравенство
  174. bool operator !=(const big_integer& left, const big_integer& right) {
  175.     return !(left == right);
  176. }
  177.  
  178. // проверяет, является ли левый операнд меньше либо равен правого
  179. bool operator <=(const big_integer& left, const big_integer& right) {
  180.     return (left < right || left == right);
  181. }
  182.  
  183. // проверяет, является ли левый операнд больше правого
  184. bool operator >(const big_integer& left, const big_integer& right) {
  185.     return !(left <= right);
  186. }
  187.  
  188. // проверяет, является ли левый операнд больше либо равен правого
  189. bool operator >=(const big_integer& left, const big_integer& right) {
  190.     return !(left < right);
  191. }
  192.  
  193. // складывает два числа
  194. const big_integer operator +(big_integer left, const big_integer& right) {
  195.     if (left._is_negative) {
  196.         if (right._is_negative) return -(-left + (-right));
  197.         else return right - (-left);
  198.     }
  199.     else if (right._is_negative) return left - (-right);
  200.     int carry = 0;
  201.     for (size_t i = 0; i < std::max(left._digits.size(), right._digits.size()) || carry != 0; ++i) {
  202.         if (i == left._digits.size()) left._digits.push_back(0);
  203.         left._digits[i] += carry + (i < right._digits.size() ? right._digits[i] : 0);
  204.         carry = left._digits[i] >= big_integer::BASE;
  205.         if (carry != 0) left._digits[i] -= big_integer::BASE;
  206.     }
  207.  
  208.     return left;
  209. }
  210.  
  211. // прибавляет к текущему числу новое
  212. big_integer& big_integer::operator +=(const big_integer& value) {
  213.     return *this = (*this + value);
  214. }
  215.  
  216. // префиксный инкремент
  217. const big_integer big_integer::operator++() {
  218.     return (*this += 1);
  219. }
  220.  
  221. // преобразует число к строке
  222. big_integer::operator std::string() const {
  223.     std::stringstream ss;
  224.     ss << *this;
  225.     return ss.str();
  226. }
  227.  
  228. // преобразует signed char к big_integer
  229. big_integer::big_integer(signed char c) {
  230.     if (c < 0) this->_is_negative = true;
  231.     else this->_is_negative = false;
  232.     this->_digits.push_back(std::abs(c));
  233. }
  234.  
  235. // преобразует unsigned char к big_integer
  236. big_integer::big_integer(unsigned char c) {
  237.     this->_is_negative = false;
  238.     this->_digits.push_back(c);
  239. }
  240.  
  241. // преобразует signed short к big_integer
  242. big_integer::big_integer(signed short s) {
  243.     if (s < 0) this->_is_negative = true;
  244.     else this->_is_negative = false;
  245.     this->_digits.push_back(std::abs(s));
  246. }
  247.  
  248. // преобразует unsigned short к big_integer
  249. big_integer::big_integer(unsigned short s) {
  250.     this->_is_negative = false;
  251.     this->_digits.push_back(s);
  252. }
  253.  
  254. // преобразует signed int к big_integer
  255. big_integer::big_integer(signed int i) {
  256.     if (i < 0) this->_is_negative = true;
  257.     else this->_is_negative = false;
  258.     this->_digits.push_back(std::abs(i) % big_integer::BASE);
  259.     i /= big_integer::BASE;
  260.     if (i != 0) this->_digits.push_back(std::abs(i));
  261. }
  262.  
  263. // преобразует unsigned int к big_integer
  264. big_integer::big_integer(unsigned int i) {
  265.     this->_digits.push_back(i % big_integer::BASE);
  266.     i /= big_integer::BASE;
  267.     if (i != 0) this->_digits.push_back(i);
  268. }
  269.  
  270. // преобразует signed long к big_integer
  271. big_integer::big_integer(signed long l) {
  272.     if (l < 0) this->_is_negative = true;
  273.     else this->_is_negative = false;
  274.     this->_digits.push_back(std::abs(l) % big_integer::BASE);
  275.     l /= big_integer::BASE;
  276.     if (l != 0) this->_digits.push_back(std::abs(l));
  277. }
  278.  
  279. // преобразует unsigned long к big_integer
  280. big_integer::big_integer(unsigned long l) {
  281.     this->_digits.push_back(l % big_integer::BASE);
  282.     l /= big_integer::BASE;
  283.     if (l != 0) this->_digits.push_back(l);
  284. }
  285.  
  286. // преобразует signed long long к big_integer
  287. big_integer::big_integer(signed long long l) {
  288.     if (l < 0) { this->_is_negative = true; l = -l; }
  289.     else this->_is_negative = false;
  290.     do {
  291.         this->_digits.push_back(l % big_integer::BASE);
  292.         l /= big_integer::BASE;
  293.     } while (l != 0);
  294. }
  295.  
  296. // преобразует unsigned long long к big_integer
  297. big_integer::big_integer(unsigned long long l) {
  298.     this->_is_negative = false;
  299.     do {
  300.         this->_digits.push_back(l % big_integer::BASE);
  301.         l /= big_integer::BASE;
  302.     } while (l != 0);
  303. }
  304.  
  305. // постфиксный инкремент
  306. const big_integer big_integer::operator ++(int) {
  307.     big_integer bi(*this);
  308.     *this += 1;
  309.     return bi;
  310. }
  311.  
  312. // префиксный декремент
  313. const big_integer big_integer::operator --() {
  314.     return *this -= 1;
  315. }
  316.  
  317. // постфиксный декремент
  318. const big_integer big_integer::operator --(int) {
  319.     big_integer bi(*this);
  320.     *this -= 1;
  321.     return bi;
  322. }
  323.  
  324. // вычитает два числа
  325. const big_integer operator -(big_integer left, const big_integer& right) {
  326.     if (right._is_negative) return left + (-right);
  327.     else if (left._is_negative) return -(-left + right);
  328.     else if (left < right) return -(right - left);
  329.     int carry = 0;
  330.     for (size_t i = 0; i < right._digits.size() || carry != 0; ++i) {
  331.         left._digits[i] -= carry + (i < right._digits.size() ? right._digits[i] : 0);
  332.         carry = left._digits[i] < 0;
  333.         if (carry != 0) left._digits[i] += big_integer::BASE;
  334.     }
  335.  
  336.     left._remove_leading_zeros();
  337.     return left;
  338. }
  339.  
  340. // вычитает из текущего числа новое
  341. big_integer& big_integer::operator -=(const big_integer& value) {
  342.     return *this = (*this - value);
  343. }
  344.  
  345. // перемножает два числа
  346. const big_integer operator *(const big_integer& left, const big_integer& right) {
  347.     big_integer result;
  348.     result._digits.resize(left._digits.size() + right._digits.size());
  349.     for (size_t i = 0; i < left._digits.size(); ++i) {
  350.         int carry = 0;
  351.         for (size_t j = 0; j < right._digits.size() || carry != 0; ++j) {
  352.             long long cur = result._digits[i + j] +
  353.                 left._digits[i] * 1LL * (j < right._digits.size() ? right._digits[j] : 0) + carry;
  354.             result._digits[i + j] = static_cast<int>(cur % big_integer::BASE);
  355.             carry = static_cast<int>(cur / big_integer::BASE);
  356.         }
  357.     }
  358.  
  359.     result._is_negative = left._is_negative != right._is_negative;
  360.     result._remove_leading_zeros();
  361.     return result;
  362. }
  363.  
  364. // домножает текущее число на указанное
  365. big_integer& big_integer::operator *=(const big_integer& value) {
  366.     return *this = (*this * value);
  367. }
  368.  
  369. // сдвигает все разряды на 1 вправо (домножает на BASE)
  370. void big_integer::_shift_right() {
  371.     if (this->_digits.size() == 0) {
  372.         this->_digits.push_back(0);
  373.         return;
  374.     }
  375.     this->_digits.push_back(this->_digits[this->_digits.size() - 1]);
  376.     for (size_t i = this->_digits.size() - 2; i > 0; --i) this->_digits[i] = this->_digits[i - 1];
  377.     this->_digits[0] = 0;
  378. }
  379.  
  380. // делит два числа
  381. const big_integer operator /(const big_integer& left, const big_integer& right) {
  382.     if (right == 0) throw big_integer::divide_by_zero();
  383.     big_integer b = right;
  384.     b._is_negative = false;
  385.     big_integer result, current;
  386.     result._digits.resize(left._digits.size());
  387.     for (long long i = static_cast<long long>(left._digits.size()) - 1; i >= 0; --i) {
  388.         current._shift_right();
  389.         current._digits[0] = left._digits[i];
  390.         current._remove_leading_zeros();
  391.         int x = 0, l = 0, r = big_integer::BASE;
  392.         while (l <= r) {
  393.             int m = (l + r) / 2;
  394.             big_integer t = b * m;
  395.             if (t <= current) {
  396.                 x = m;
  397.                 l = m + 1;
  398.             }
  399.             else r = m - 1;
  400.         }
  401.  
  402.         result._digits[i] = x;
  403.         current = current - b * x;
  404.     }
  405.  
  406.     result._is_negative = left._is_negative != right._is_negative;
  407.     result._remove_leading_zeros();
  408.     return result;
  409. }
  410.  
  411. // делит текущее число на указанное
  412. big_integer& big_integer::operator /=(const big_integer& value) {
  413.     return *this = (*this / value);
  414. }
  415.  
  416. // возвращает остаток от деления двух чисел
  417. const big_integer operator %(const big_integer& left, const big_integer& right) {
  418.     big_integer result = left - (left / right) * right;
  419.     if (result._is_negative) result += right;
  420.     return result;
  421. }
  422.  
  423. // присваивает текущему числу остаток от деления на другое число
  424. big_integer& big_integer::operator %=(const big_integer& value) {
  425.     return *this = (*this % value);
  426. }
  427.  
  428. // проверяет, является ли текущее число нечетным
  429. bool big_integer::odd() const {
  430.     if (this->_digits.size() == 0) return false;
  431.     return this->_digits[0] & 1;
  432. }
  433.  
  434. // проверяет, является ли текущее число четным
  435. bool big_integer::even() const {
  436.     return !this->even();
  437. }
  438.  
  439. // возводит текущее число в указанную степень
  440. const big_integer big_integer::pow(big_integer n) const {
  441.     big_integer a(*this), result(1);
  442.     while (n != 0) {
  443.         if (n.odd()) result *= a;
  444.         a *= a;
  445.         n /= 2;
  446.     }
  447.  
  448.     return result;
  449. }
Advertisement
Add Comment
Please, Sign In to add comment