#include<bits/stdc++.h>
using namespace std;
class HighPrecision {
public:
HighPrecision();
HighPrecision(const std::string& num_str);
HighPrecision(const HighPrecision& other);
~HighPrecision();
HighPrecision& operator=(const HighPrecision& other);
HighPrecision operator+(const HighPrecision& other) const;
HighPrecision operator-(const HighPrecision& other) const;
HighPrecision operator*(const HighPrecision& other) const;
HighPrecision operator/(const HighPrecision& other) const;
HighPrecision operator<<(int shift) const;
HighPrecision operator>>(int shift) const;
bool operator<(const HighPrecision& other) const;
bool operator>(const HighPrecision& other) const;
bool operator<=(const HighPrecision& other) const;
bool operator>=(const HighPrecision& other) const;
bool operator==(const HighPrecision& other) const;
bool operator!=(const HighPrecision& other) const;
HighPrecision& operator+=(const HighPrecision& other);
HighPrecision& operator-=(const HighPrecision& other);
HighPrecision& operator*=(const HighPrecision& other);
HighPrecision& operator/=(const HighPrecision& other);
HighPrecision& operator<<=(int shift);
HighPrecision& operator>>=(int shift);
HighPrecision& operator++();
HighPrecision operator++(int);
HighPrecision& operator--();
HighPrecision operator--(int);
std::string to_string() const;
public:
std::vector<int> digits_;
bool is_negative_;
void remove_leading_zeros_();
void from_string_(const std::string& num_str);
void from_int_(int num);
void from_long_long_(long long num);
void from_unsigned_long_long_(unsigned long long num);
void from_double_(double num);
void add_(const HighPrecision& other);
void subtract_(const HighPrecision& other);
void multiply_(const HighPrecision& other);
void divide_(const HighPrecision& other);
void shift_left_(int shift);
void shift_right_(int shift);
bool less_(const HighPrecision& other) const;
bool equal_(const HighPrecision& other) const;
};
HighPrecision::HighPrecision() {
digits_.push_back(0);
is_negative_ = false;
}
HighPrecision::HighPrecision(const HighPrecision& other) {
digits_ = other.digits_;
is_negative_ = other.is_negative_;
}
HighPrecision::~HighPrecision() {}
HighPrecision& HighPrecision::operator=(const HighPrecision& other) {
digits_ = other.digits_;
is_negative_ = other.is_negative_;
return *this;
}
HighPrecision HighPrecision::operator+(const HighPrecision& other) const {
HighPrecision result(*this);
result += other;
return result;
}
HighPrecision HighPrecision::operator-(const HighPrecision& other) const {
HighPrecision result(*this);
result -= other;
return result;
}
HighPrecision HighPrecision::operator*(const HighPrecision& other) const {
HighPrecision result(*this);
result *= other;
return result;
}
HighPrecision HighPrecision::operator/(const HighPrecision& other) const {
HighPrecision result(*this);
result /= other;
return result;
}
HighPrecision HighPrecision::operator<<(int shift) const {
HighPrecision result(*this);
result <<= shift;
return result;
}
HighPrecision HighPrecision::operator>>(int shift) const {
HighPrecision result(*this);
result >>= shift;
return result;
}
bool HighPrecision::operator<(const HighPrecision& other) const {
return less_(other);
}
bool HighPrecision::operator>(const HighPrecision& other) const {
return other.less_(*this);
}
bool HighPrecision::operator<=(const HighPrecision& other) const {
return !other.less_(*this);
}
bool HighPrecision::operator>=(const HighPrecision& other) const {
return !less_(other);
}
bool HighPrecision::operator==(const HighPrecision& other) const {
return equal_(other);
}
bool HighPrecision::operator!=(const HighPrecision& other) const {
return !equal_(other);
}
HighPrecision& HighPrecision::operator+=(const HighPrecision& other) {
if (is_negative_ == other.is_negative_) {
add_(other);
} else {
if (less_(other)) {
HighPrecision temp(other);
temp.subtract_(*this);
subtract_(temp);
is_negative_ = temp.is_negative_;
} else {
subtract_(other);
}
}
remove_leading_zeros_();
return *this;
}
HighPrecision& HighPrecision::operator-=(const HighPrecision& other) {
if (is_negative_ != other.is_negative_) {
add_(other);
} else {
if (less_(other)) {
HighPrecision temp(other);
temp.subtract_(*this);
*this = temp;
is_negative_ = !is_negative_;
} else {
subtract_(other);
}
}
remove_leading_zeros_();
return *this;
}
HighPrecision& HighPrecision::operator*=(const HighPrecision& other) {
multiply_(other);
remove_leading_zeros_();
return *this;
}
HighPrecision& HighPrecision::operator/=(const HighPrecision& other) {
divide_(other);
remove_leading_zeros_();
return *this;
}
HighPrecision& HighPrecision::operator<<=(int shift) {
shift_left_(shift);
return *this;
}
HighPrecision& HighPrecision::operator>>=(int shift) {
shift_right_(shift);
return *this;
}
HighPrecision& HighPrecision::operator++() {
HighPrecision one("1");
add_(one);
remove_leading_zeros_();
return *this;
}
HighPrecision HighPrecision::operator++(int) {
HighPrecision result(*this);
operator++();
return result;
}
HighPrecision& HighPrecision::operator--() {
HighPrecision one("1");
subtract_(one);
remove_leading_zeros_();
return *this;
}
HighPrecision HighPrecision::operator--(int) {
HighPrecision result(*this);
operator--();
return result;
}
std::string HighPrecision::to_string() const {
std::string result;
if (is_negative_) {
result.push_back('-');
}
for (auto it = digits_.rbegin(); it != digits_.rend(); ++it) {
result.push_back('0' + *it);
}
return result;
}
void HighPrecision::remove_leading_zeros_() {
while (digits_.size() > 1 && digits_.back() == 0) {
digits_.pop_back();
}
if (digits_.size() == 1 && digits_.back()) {
is_negative_ = false;
}
}