Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef BIGINT_H
- #define BIGINT_H
- #include <vector>
- #include <string>
- typedef unsigned short elem_t;
- class BigInt
- {
- public:
- explicit BigInt(long long);
- explicit BigInt(const std::vector<elem_t>&);
- explicit BigInt(const std::string&);
- ~BigInt();
- BigInt operator + (const BigInt&);
- BigInt operator - (const BigInt&);
- BigInt operator * (const BigInt&);
- BigInt operator / (const BigInt&);
- BigInt operator % (const BigInt&);
- bool operator > (const BigInt&);
- bool operator < (const BigInt&);
- bool operator >= (const BigInt&);
- bool operator <= (const BigInt&);
- bool operator == (const BigInt&);
- bool operator != (const BigInt&);
- void operator = (const BigInt&);
- void operator += (const BigInt&);
- void operator -= (const BigInt&);
- void operator *= (const BigInt&);
- void operator /= (const BigInt&);
- void operator %= (const BigInt&);
- void operator ++ ();
- void operator ++ (int);
- void operator -- ();
- void operator -- (int);
- BigInt operator + (const long long);
- BigInt operator - (const long long);
- BigInt operator * (const long long);
- BigInt operator / (const long long);
- BigInt operator % (const long long);
- bool operator > (const long long);
- bool operator < (const long long);
- bool operator >= (const long long);
- bool operator <= (const long long);
- bool operator == (const long long);
- bool operator != (const long long);
- void operator = (const long long);
- void operator += (const long long);
- void operator -= (const long long);
- void operator *= (const long long);
- void operator /= (const long long);
- void operator %= (const long long);
- BigInt pow(const BigInt&);
- std::pair<BigInt, int> sqrt(const BigInt&);
- BigInt abs() const;
- BigInt gcd(const BigInt&);
- BigInt swap(const BigInt&);
- BigInt copy() const;
- std::string to_string();
- private:
- std::vector<elem_t> collect;
- BigInt change_signe() const;
- BigInt minus(const BigInt&) const;
- BigInt plus(const BigInt&) const;
- };
- std::vector<elem_t > convert(const long long);
- BigInt convert_big(const long long);
- #endif //BIGINT_H
- #include "library.h"
- #include <cassert>
- #include <deque>
- #include <algorithm>
- #define LOOP while (true)
- inline void assertmsg(const bool expression, const char* message)
- {
- assert(((void)message, expression));
- }
- std::vector<elem_t > convert(const long long right)
- {
- std::deque<elem_t> right_collect;
- long long abs_right = std::abs(right);
- while (abs_right > 0)
- {
- right_collect.push_front(abs_right % 10);
- abs_right /= 10;
- }
- if (right < 0) right_collect.push_front(10);
- std::vector<elem_t> res_vec(right_collect.size());
- std::move(right_collect.begin(), right_collect.end(), res_vec.begin());
- return res_vec;
- }
- inline BigInt convert_big(const long long right)
- {
- BigInt res(std::move(convert(right)));
- return res;
- }
- BigInt::BigInt(long long construct)
- {
- std::deque<elem_t> new_int;
- bool otr = construct < 0;
- construct = construct > 0 ? construct : -construct;
- while (construct > 0)
- {
- new_int.push_front(construct % 10);
- construct /= 10;
- }
- if (otr) new_int.push_front(10);
- std::move(new_int.begin(), new_int.end(), collect.begin());
- }
- BigInt::BigInt(const std::vector<elem_t>& construct)
- {
- std::copy(construct.begin(), construct.end(), collect.begin());
- }
- BigInt::BigInt(const std::string& construct)
- {
- for (char i : construct)
- {
- if (i == '-') collect.push_back(10);
- else
- {
- assertmsg(i < 48 || i > 57, "Incorrect string to construct BigInt (string_type constructor)");
- collect.push_back(i - 48);
- }
- }
- }
- BigInt BigInt::plus(const BigInt& right) const
- {
- std::deque<elem_t> res_d;
- elem_t per = 0;
- size_t l_ptr = collect.size() - 1;
- size_t r_ptr = right.collect.size() - 1;
- LOOP
- {
- res_d.push_front((collect[l_ptr] + right.collect[r_ptr] + per) % 10);
- per = collect[l_ptr] + right.collect[r_ptr] + per > 9 ? 1 : 0;
- if (l_ptr == 0 || r_ptr == 0) break;
- l_ptr--, r_ptr--;
- }
- while (l_ptr != 0)
- {
- res_d.push_front((collect[l_ptr] + per) % 10);
- per = collect[l_ptr] + per > 9 ? 1 : 0;
- l_ptr--;
- }
- while (r_ptr != 0)
- {
- res_d.push_front((right.collect[r_ptr] + per) % 10);
- per = right.collect[r_ptr] + per > 9 ? 1 : 0;
- r_ptr--;
- }
- if (per == 1)
- res_d.push_front(1);
- std::vector<elem_t>res_vec;
- std::move(res_d.begin(), res_d.end(), res_vec.begin());
- BigInt res(res_vec);
- return res;
- }
- BigInt BigInt::operator +(const BigInt& right)
- {
- assertmsg(collect.empty(),"Left argument is empty (operator +)");
- assertmsg(right.collect.empty(),"Right argument is empty (operator +)");
- if (right.collect[0] != 10 && collect[0] != 10) // + +
- return this->plus(right);
- else if (this->collect[0] == 10 && right.collect[0] == 10) // - -
- return (this->abs().plus(right.abs())).change_signe();
- return *this - right;
- }
- BigInt BigInt::operator +(const long long right)
- {
- assertmsg(collect.empty(),"Left argument is empty (operator +)");
- BigInt res(convert_big(right));
- return this->plus(res);
- }
- BigInt BigInt::minus(const BigInt& right) const
- {
- std::deque<elem_t> res_d;
- size_t l_ptr = (*this).collect.size() - 1;
- size_t r_ptr = right.collect.size() - 1;
- std::vector<elem_t> right_cpy(right.collect.size());
- std::vector<elem_t> this_cpy((*this).collect.size());
- std::copy(right.collect.begin(), right.collect.end(), right_cpy.begin());
- std::copy((*this).collect.begin(), (*this).collect.end(), this_cpy.begin());
- while (r_ptr >= 0)
- {
- if (right_cpy[r_ptr] == 10) break;
- else
- {
- if (this_cpy[l_ptr] >= right_cpy[r_ptr])
- res_d.push_front(this_cpy[l_ptr] - right_cpy[r_ptr]);
- else
- {
- size_t i = 1;
- while (this_cpy[l_ptr - i] == 0) ++i;
- this_cpy[l_ptr - i]--;
- res_d.push_front(this_cpy[l_ptr] + 10 - right_cpy[r_ptr]);
- }
- if (r_ptr == 0){l_ptr--; break;}
- r_ptr--, l_ptr--;
- }
- }
- while (l_ptr > 0)
- {
- res_d.push_front(this_cpy[l_ptr]);
- l_ptr--;
- }
- bool otr = false;
- if (this_cpy[0] != 10)
- res_d.push_front(this_cpy[0]);
- else
- otr = true;
- std::vector<elem_t> res_vec(res_d.size() - (otr ? 0 : 1));
- if (otr) res_vec[0] = 10;
- std::move(res_d.begin(), res_d.end(), res_vec.begin() + (otr ? 1 : 0));
- BigInt res(res_vec);
- return res;
- }
- BigInt BigInt::operator -(const BigInt& right)
- {
- assertmsg(collect.empty(),"Left argument is empty (operator -)");
- assertmsg(right.collect.empty(),"Right argument is empty (operator -)");
- if (collect[0] != 10 && right.collect[0] == 10) // + -
- return *this + right.abs();
- if (collect[0] == 10 && right.collect[0] != 10) // - +
- return ((*this).abs() + right).change_signe();
- // - - / + +
- if ((*this).abs() > right.abs())
- return this->minus(right);
- else if ((*this).abs() < right.abs())
- return right.minus(*this);
- else
- {
- std::vector<elem_t> res_vec(1, 0);
- BigInt res(res_vec);
- return res;
- }
- }
- BigInt BigInt::operator -(const long long right)
- {
- assertmsg(collect.empty(),"Left argument is empty (operator -)");
- BigInt res(convert_big(right));
- return *this - res;
- }
- BigInt BigInt::operator *(const BigInt& right)
- {
- BigInt res(convert_big(0));
- for (BigInt i = convert_big(0); i < right; ++i)
- res += i;
- return res;
- }
- BigInt BigInt::operator *(const long long right)
- {
- BigInt res(convert_big(0));
- BigInt Right(convert_big(right));
- for (BigInt i = convert_big(0); i < Right; ++i)
- res += i;
- return res;
- }
- bool BigInt::operator >(const BigInt& right)
- {
- if (this->collect[0] == 10)
- {
- if (right.collect[0] != 10) return false;
- else
- {
- if ((*this).collect.size() > right.collect.size()) return false;
- else if ((*this).collect.size() < right.collect.size()) return true;
- else
- {
- for (size_t i = 1; i < right.collect.size(); ++i)
- {
- if ((*this).collect[i] > right.collect[i]) return false;
- else if ((*this).collect[i] < right.collect[i]) return true;
- }
- return false;
- }
- }
- }
- else
- {
- if (right.collect[0] == 10) return true;
- else
- {
- if ((*this).collect.size() > right.collect.size()) return true;
- else if ((*this).collect.size() < right.collect.size()) return false;
- else
- {
- for (size_t i = 0; i < right.collect.size(); ++i)
- {
- if ((*this).collect[i] > right.collect[i]) return true;
- else if ((*this).collect[i] < right.collect[i]) return false;
- }
- return false;
- }
- }
- }
- }
- inline bool BigInt::operator >(const long long right)
- {
- BigInt res(convert_big(right));
- return *this > res;
- }
- inline bool BigInt::operator ==(const BigInt& right)
- {
- return std::equal((*this).collect.begin(), (*this).collect.end(),
- right.collect.begin(), right.collect.end());
- }
- inline bool BigInt::operator ==(const long long right)
- {
- std::vector<elem_t> res_collect(std::move(convert(right)));
- return std::equal((*this).collect.begin(), (*this).collect.end(),
- res_collect.begin(), res_collect.end());
- }
- inline bool BigInt::operator !=(const BigInt& right)
- {
- return !(*this == right);
- }
- inline bool BigInt::operator !=(const long long right)
- {
- std::vector<elem_t> res_collect(std::move(convert(right)));;
- return !std::equal((*this).collect.begin(), (*this).collect.end(),
- res_collect.begin(), res_collect.end());
- }
- inline bool BigInt::operator >=(const BigInt& right)
- {
- return *this > right ? true : *this == right;
- }
- inline bool BigInt::operator >=(const long long right)
- {
- return *this > right ? true : *this == right;
- }
- inline bool BigInt::operator <(const BigInt& right)
- {
- return !(*this >= right);
- }
- inline bool BigInt::operator <(const long long right)
- {
- return !(*this >= right);
- }
- inline bool BigInt::operator <=(const BigInt& right)
- {
- return *this == right ? true : *this < right;
- }
- inline bool BigInt::operator <=(const long long right)
- {
- return *this == right ? true : *this < right;
- }
- inline void BigInt::operator =(const BigInt& right)
- {
- (*this).collect.resize(right.collect.size());
- std::move(right.collect.begin(), right.collect.end(), (*this).collect.begin());
- }
- inline void BigInt::operator =(const long long right)
- {
- std::vector<elem_t> res_collect(std::move(convert(right)));
- (*this).collect.resize(res_collect.size());
- std::move(res_collect.begin(), res_collect.end(), (*this).collect.begin());
- }
- inline void BigInt::operator +=(const BigInt& right)
- {
- *this = *this + right;
- }
- inline void BigInt::operator +=(const long long right)
- {
- *this = *this + right;
- }
- inline void BigInt::operator -=(const BigInt& right)
- {
- *this = *this - right;
- }
- inline void BigInt::operator -=(const long long right)
- {
- *this = *this - right;
- }
- inline void BigInt::operator *=(const BigInt& right)
- {
- *this = *this * right;
- }
- inline void BigInt::operator *=(const long long right)
- {
- *this = *this * right;
- }
- inline void BigInt::operator++()
- {
- *this = *this + 1;
- }
- inline void BigInt::operator--()
- {
- *this = *this - 1;
- }
- BigInt BigInt::abs() const
- {
- assertmsg(collect.empty(),"Argument is empty (abs method)");
- if (collect[0] != 0)
- return *this;
- else
- {
- std::vector<elem_t> res_vec(collect.size() - 1);
- BigInt res(res_vec);
- std::copy(collect.begin() + 1, collect.end(), res.collect.begin());
- return res;
- }
- }
- BigInt BigInt::change_signe() const
- {
- if (this->collect[0] != 10)
- {
- std::vector<elem_t> res_v((*this).collect.size() + 1);
- std::copy((*this).collect.begin(), (*this).collect.end(), res_v.begin() + 1);
- res_v[0] = 10;
- BigInt res(res_v);
- return res;
- }
- else return (*this).abs();
- }
- inline BigInt BigInt::copy() const
- {
- return *this;
- }
- std::string BigInt::to_string()
- {
- std::string out(this->collect.size(), '0');
- for (elem_t i = 0; i < this->collect.size(); ++i)
- out[i] = this->collect[i] == 10 ? '-' : this->collect[i] + 48;
- return out;
- }
- BigInt::~BigInt() = default;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement