From d9f6461945c6550cabab9676f7f1e156cc3f5801 Mon Sep 17 00:00:00 2001 From: Igor Egorov Date: Sun, 13 Dec 2020 15:18:02 +0300 Subject: [PATCH 1/6] Implemented everything except division and remnant. --- module-1/homework/BigInteger/biginteger.cpp | 335 ++++++++++++++++++++ module-1/homework/BigInteger/biginteger.h | 65 ++++ 2 files changed, 400 insertions(+) create mode 100644 module-1/homework/BigInteger/biginteger.cpp create mode 100644 module-1/homework/BigInteger/biginteger.h diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp new file mode 100644 index 00000000..fb8baed9 --- /dev/null +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -0,0 +1,335 @@ +#include "biginteger.h" +#include + +BigInteger::BigInteger() { + clear(); + sign = NEUTRAL; + big_number.push_back(0); +} + +BigInteger::BigInteger(int num) { + clear(); + if (num == 0) { + sign = NEUTRAL; + big_number.push_back(0); + } + else { + if (num < 0) { + sign = NEGATIVE; + num = -num; + } else + sign = POSITIVE; + big_number.push_back(num % MAX_VALUE); + big_number.push_back(num / MAX_VALUE); + } + clear_back(); +} + +BigInteger::BigInteger(const std::string& num) { + clear(); + if (!check_string_to_num(num)) { + sign = NEUTRAL; + big_number.push_back(0); + } else { + int end_of_num = 0; + sign = POSITIVE; + if (num[0] == '-') { + sign = NEGATIVE; + end_of_num++; + } + if (num[0] == '+') + end_of_num++; + int cur_pos = num.size() - 1; + int cur_pos_in_part = 1; + int num_part = 0; + while (cur_pos >= end_of_num) { + if (cur_pos_in_part == MAX_VALUE) { + big_number.push_back(num_part); + num_part = 0; + cur_pos_in_part = 1; + } + num_part += static_cast(num[cur_pos] - '0') * cur_pos_in_part; + cur_pos_in_part *= 10; + cur_pos--; + } + if (cur_pos_in_part > 1) + big_number.push_back(num_part); + clear_back(); + } +} + +BigInteger::BigInteger(const char s, const std::vector& big_num) { + sign = s; + big_number = big_num; +} + +bool BigInteger::check_string_to_num(const std::string& input) { + if (input.size() == 0) + return 0; + size_t i = 0; + if (input[i] == '-' || input[i] == '+') + i++; + int cnt = 0; + for (i; i < input.size(); i++) { + if (!(input[i] >= '0' && input[i] <= '9')) + return false; + cnt++; + } + if (cnt > 0) + return true; + return false; +} + +void BigInteger::clear() { + sign = NEUTRAL; + big_number.clear(); +} + +std::string BigInteger::toString() const { + std::string answer; + if (sign == NEGATIVE) + answer.push_back('-'); + for (int i = big_number.size() - 1; i >= 0; i--) { + if (i != big_number.size() - 1) { + int cur_num = big_number[i]; + if (cur_num == 0) + for (int i = 0; i < POS_IN_MAX_VALUE - 1; i++) + answer.push_back('0'); + else + while (cur_num < MAX_VALUE / 10) { + cur_num *= 10; + answer.push_back('0'); + } + } + answer += std::to_string(big_number[i]); + } +} + +void BigInteger::clear_back() { + while (big_number.size() > 1 && big_number[big_number.size() - 1] == 0) + big_number.pop_back(); + if (big_number.size() == 1 && big_number[0] == 0) + sign = NEUTRAL; +} + +BigInteger& BigInteger::operator=(const BigInteger& big_num) { + big_number = big_num.big_number; + sign = big_num.sign; + return *this; +} + +BigInteger& BigInteger::operator=(int num) { + *this = BigInteger(num); + return *this; +} + +BigInteger& BigInteger::operator=(const std::string& num) { + *this = BigInteger(num); + return *this; +} + +bool operator==(const BigInteger& left, const BigInteger& right) { + if (left.sign != right.sign || left.big_number.size() != right.big_number.size()) + return false; + for (int i = 0; i < left.big_number.size(); i++) + if (left.big_number[i] != right.big_number[i]) + return false; + return true; +} + +bool operator!=(const BigInteger& left, const BigInteger& right) { + return !(left == right); +} + +bool operator<(const BigInteger& left, const BigInteger& right) { + if (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + return (-right) < (-left); + if (left.sign == BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) + return true; + if (left.sign != BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + return false; + if (right.big_number.size() > left.big_number.size()) + return true; + if (right.big_number.size() < left.big_number.size()) + return false; + for (size_t i = 0; i < left.big_number.size(); i++) { + if (left.big_number[i] < right.big_number[i]) + return true; + if (left.big_number[i] > right.big_number[i]) + return false; + } + return false; +} + +bool operator>(const BigInteger& left, const BigInteger& right) { + return (right < left); +} + +bool operator<=(const BigInteger& left, const BigInteger& right) { + return (left == right || left < right); +} + +bool operator>=(const BigInteger& left, const BigInteger& right) { + return (left == right || left > right); +} + +BigInteger& BigInteger::operator-() const{ + if (sign == NEGATIVE) + return *(new BigInteger(POSITIVE, big_number)); + if (sign == POSITIVE) + return *(new BigInteger(NEGATIVE, big_number)); + return *(new BigInteger(NEUTRAL, big_number)); +} + +BigInteger operator-(const BigInteger& left, const BigInteger& right) { + if (left.sign == BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) + return -((-left) + right); + if (left.sign != BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + return (left + (-right)); + if (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + return (-right) - (-left); + if (right > left) + return -(right - left); + int carry = 0; + BigInteger answer; + answer.sign = BigInteger::POSITIVE; + for (int i = 0; i < right.big_number.size(); i++) { + int step_ans = left.big_number[i] - right.big_number[i] - carry; + if (step_ans < 0) { + step_ans += BigInteger::MAX_VALUE; + carry = 1; + } + answer.big_number.push_back(step_ans); + } + for (int i = right.big_number.size(); i < left.big_number.size() && carry != 0; i++) { + int step_ans = left.big_number[i] - carry; + if (step_ans < 0) { + step_ans += BigInteger::MAX_VALUE; + carry = 1; + } + answer.big_number.push_back(step_ans); + } + answer.clear_back(); + return answer; +} + +BigInteger operator+(const BigInteger& left, const BigInteger& right) { + if (left > right) + return right + left; + if (left.sign == BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) + return right - (-left); + if (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + return -((-left) + (-right)); + BigInteger answer; + int carry = 0; + answer.sign = BigInteger::POSITIVE; + for (size_t i = 0; i < left.big_number.size(); i++) { + int step_ans = carry + left.big_number[i] + right.big_number[i]; + carry = step_ans / BigInteger::MAX_VALUE; + step_ans %= BigInteger::MAX_VALUE; + answer.big_number.push_back(step_ans); + } + for (size_t i = left.big_number.size(); i < right.big_number.size(); i++) { + int step_ans = carry + right.big_number[i]; + carry = step_ans / BigInteger::MAX_VALUE; + step_ans %= BigInteger::MAX_VALUE; + answer.big_number.push_back(step_ans); + } + answer.big_number.push_back(carry); + answer.clear_back(); + return answer; +} + +BigInteger operator*(const BigInteger& left, const BigInteger& right) { + if (left.sign == BigInteger::NEUTRAL || right.sign == BigInteger::NEUTRAL) + return BigInteger(); + std::vector ans_num(left.big_number.size() + right.big_number.size()); + for (size_t i = 0; i < left.big_number.size(); i++) { + int carry = 0; + for (int j = 0; j < right.big_number.size() || carry > 0; j++) { + long long step_ans = (j >= right.big_number.size() ? 0 : left.big_number[i] * right.big_number[j]) + carry; + carry = step_ans / BigInteger::MAX_VALUE; + step_ans %= BigInteger::MAX_VALUE; + ans_num[i + j] = static_cast(step_ans); + } + } + BigInteger answer = BigInteger(BigInteger::NEGATIVE, ans_num); + if ((left.sign != BigInteger::NEGATIVE && left.sign != BigInteger::NEGATIVE) || + (left.sign == BigInteger::NEGATIVE && left.sign == BigInteger::NEGATIVE)) + answer.sign = BigInteger::POSITIVE; + answer.clear_back(); + return answer; +} + +BigInteger operator/(const BigInteger& left, const BigInteger& right) { + //write code +} + +BigInteger operator%(const BigInteger& left, const BigInteger& right) { + //write code +} + +BigInteger& BigInteger::operator+=(const BigInteger& right) { + *this = (*this + right); + return *this; +} + +BigInteger& BigInteger::operator-=(const BigInteger& right) { + *this = (*this - right); + return *this; +} + +BigInteger& BigInteger::operator*=(const BigInteger& right) { + *this = (*this * right); + return *this; +} + +BigInteger& BigInteger::operator/=(const BigInteger& right) { + *this = (*this / right); + return *this; +} + +BigInteger& BigInteger::operator%=(const BigInteger& right) { + *this = (*this % right); + return *this; +} + +std::istream& operator>>(std::istream& in, BigInteger& big_num) { + std::string input; + in >> input; + big_num = input; + return in; +} + +std::ostream& operator<<(std::ostream& out, const BigInteger& big_num) { + out << big_num.toString(); + return out; +} + +BigInteger::operator bool() const { + return sign != NEUTRAL; +} + +BigInteger& BigInteger::operator++() { + BigInteger one = 1; + *this = *this + one; + return *this; +} + +BigInteger& BigInteger::operator--() { + BigInteger one = 1; + *this = *this - one; + return *this; +} + +BigInteger BigInteger::operator++(int) { + BigInteger ret = *this; + ++(*this); + return ret; +} + +BigInteger BigInteger::operator--(int) { + BigInteger ret = *this; + --(*this); + return ret; +} \ No newline at end of file diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h new file mode 100644 index 00000000..e2d16fd3 --- /dev/null +++ b/module-1/homework/BigInteger/biginteger.h @@ -0,0 +1,65 @@ +#include +#include + +class BigInteger { +public: + + BigInteger(); + BigInteger(int num); + BigInteger(const std::string& num); + BigInteger(const char s, const std::vector& big_num); + + std::string toString() const; + + void clear(); + + BigInteger& operator-() const; + + BigInteger& operator=(const BigInteger& big_num); + BigInteger& operator=(int num); + BigInteger& operator=(const std::string& num); + + friend bool operator==(const BigInteger& left, const BigInteger& right); + friend bool operator!=(const BigInteger& left, const BigInteger& right); + friend bool operator<(const BigInteger& left, const BigInteger& right); + friend bool operator>(const BigInteger& left, const BigInteger& right); + friend bool operator<=(const BigInteger& left, const BigInteger& right); + friend bool operator>=(const BigInteger& left, const BigInteger& right); + + friend BigInteger operator+(const BigInteger& left, const BigInteger& right); + friend BigInteger operator-(const BigInteger& left, const BigInteger& right); + friend BigInteger operator*(const BigInteger& left, const BigInteger& right); + friend BigInteger operator/(const BigInteger& left, const BigInteger& right); + friend BigInteger operator%(const BigInteger& left, const BigInteger& right); + + BigInteger& operator+=(const BigInteger& right); + BigInteger& operator-=(const BigInteger& right); + BigInteger& operator*=(const BigInteger& right); + BigInteger& operator/=(const BigInteger& right); + BigInteger& operator%=(const BigInteger& right); + + friend std::istream& operator>>(std::istream& in, BigInteger& big_num); + friend std::ostream& operator<<(std::ostream& out, const BigInteger& big_num); + + BigInteger operator++(int); + BigInteger operator--(int); + BigInteger& operator++(); + BigInteger& operator--(); + + operator bool() const; + +private: + + std::vector big_number; + char sign; + + void clear_back(); + bool check_string_to_num(const std::string& input); + + //Here will be some consts + static const int MAX_VALUE = 1e8; + static const int POS_IN_MAX_VALUE = 8; + static const char POSITIVE = '+'; + static const char NEGATIVE = '-'; + static const char NEUTRAL = '0'; +}; \ No newline at end of file From 91ddb79faa54ea34ed144e2a5183479e522d2519 Mon Sep 17 00:00:00 2001 From: Igor Egorov Date: Sun, 13 Dec 2020 23:08:37 +0300 Subject: [PATCH 2/6] Fixed bug with operator < --- module-1/homework/BigInteger/biginteger.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp index fb8baed9..cd1b4445 100644 --- a/module-1/homework/BigInteger/biginteger.cpp +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -103,6 +103,7 @@ std::string BigInteger::toString() const { } answer += std::to_string(big_number[i]); } + return answer; } void BigInteger::clear_back() { @@ -152,7 +153,7 @@ bool operator<(const BigInteger& left, const BigInteger& right) { return true; if (right.big_number.size() < left.big_number.size()) return false; - for (size_t i = 0; i < left.big_number.size(); i++) { + for (size_t i = left.big_number.size() - 1; i >= 0 ; i--) { if (left.big_number[i] < right.big_number[i]) return true; if (left.big_number[i] > right.big_number[i]) @@ -192,6 +193,7 @@ BigInteger operator-(const BigInteger& left, const BigInteger& right) { return -(right - left); int carry = 0; BigInteger answer; + answer.clear(); answer.sign = BigInteger::POSITIVE; for (int i = 0; i < right.big_number.size(); i++) { int step_ans = left.big_number[i] - right.big_number[i] - carry; @@ -222,6 +224,7 @@ BigInteger operator+(const BigInteger& left, const BigInteger& right) { return -((-left) + (-right)); BigInteger answer; int carry = 0; + answer.clear(); answer.sign = BigInteger::POSITIVE; for (size_t i = 0; i < left.big_number.size(); i++) { int step_ans = carry + left.big_number[i] + right.big_number[i]; From a3bf11b9900093ef186ac15e582be169dd4c789e Mon Sep 17 00:00:00 2001 From: Igor Egorov Date: Wed, 16 Dec 2020 00:54:22 +0300 Subject: [PATCH 3/6] Fixed bug with operator* and added compile-time constatns. --- module-1/homework/BigInteger/biginteger.cpp | 4 +++- module-1/homework/BigInteger/biginteger.h | 10 +++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp index cd1b4445..db7f7cfa 100644 --- a/module-1/homework/BigInteger/biginteger.cpp +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -250,7 +250,9 @@ BigInteger operator*(const BigInteger& left, const BigInteger& right) { for (size_t i = 0; i < left.big_number.size(); i++) { int carry = 0; for (int j = 0; j < right.big_number.size() || carry > 0; j++) { - long long step_ans = (j >= right.big_number.size() ? 0 : left.big_number[i] * right.big_number[j]) + carry; + long long step_ans = ans_num[i + j] + + (j >= right.big_number.size() ? 0 : static_cast(left.big_number[i]) * right.big_number[j]) + + carry; carry = step_ans / BigInteger::MAX_VALUE; step_ans %= BigInteger::MAX_VALUE; ans_num[i + j] = static_cast(step_ans); diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index e2d16fd3..1f1e3f64 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -57,9 +57,9 @@ class BigInteger { bool check_string_to_num(const std::string& input); //Here will be some consts - static const int MAX_VALUE = 1e8; - static const int POS_IN_MAX_VALUE = 8; - static const char POSITIVE = '+'; - static const char NEGATIVE = '-'; - static const char NEUTRAL = '0'; + static constexpr int MAX_VALUE = 1e8; + static constexpr int POS_IN_MAX_VALUE = 8; + static constexpr char POSITIVE = '+'; + static constexpr char NEGATIVE = '-'; + static constexpr char NEUTRAL = '0'; }; \ No newline at end of file From 795f711aab637aa020972e686fa4d83201cc80b6 Mon Sep 17 00:00:00 2001 From: Igor Egorov Date: Wed, 16 Dec 2020 04:04:51 +0300 Subject: [PATCH 4/6] Implementation Done! --- module-1/homework/BigInteger/biginteger.cpp | 64 +++++++++++++++++++-- module-1/homework/BigInteger/biginteger.h | 4 ++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp index db7f7cfa..dc2d9555 100644 --- a/module-1/homework/BigInteger/biginteger.cpp +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -153,7 +153,7 @@ bool operator<(const BigInteger& left, const BigInteger& right) { return true; if (right.big_number.size() < left.big_number.size()) return false; - for (size_t i = left.big_number.size() - 1; i >= 0 ; i--) { + for (int i = left.big_number.size() - 1; i >= 0 ; i--) { if (left.big_number[i] < right.big_number[i]) return true; if (left.big_number[i] > right.big_number[i]) @@ -197,14 +197,16 @@ BigInteger operator-(const BigInteger& left, const BigInteger& right) { answer.sign = BigInteger::POSITIVE; for (int i = 0; i < right.big_number.size(); i++) { int step_ans = left.big_number[i] - right.big_number[i] - carry; + carry = 0; if (step_ans < 0) { step_ans += BigInteger::MAX_VALUE; carry = 1; } answer.big_number.push_back(step_ans); } - for (int i = right.big_number.size(); i < left.big_number.size() && carry != 0; i++) { + for (int i = right.big_number.size(); i < left.big_number.size() || carry != 0; i++) { int step_ans = left.big_number[i] - carry; + carry = 0; if (step_ans < 0) { step_ans += BigInteger::MAX_VALUE; carry = 1; @@ -259,19 +261,69 @@ BigInteger operator*(const BigInteger& left, const BigInteger& right) { } } BigInteger answer = BigInteger(BigInteger::NEGATIVE, ans_num); - if ((left.sign != BigInteger::NEGATIVE && left.sign != BigInteger::NEGATIVE) || - (left.sign == BigInteger::NEGATIVE && left.sign == BigInteger::NEGATIVE)) + if ((left.sign != BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) || + (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE)) answer.sign = BigInteger::POSITIVE; answer.clear_back(); return answer; } +BigInteger BigInteger::abs(const BigInteger& big_num) { + BigInteger ans = big_num; + if (ans.sign == NEGATIVE) + ans.sign = POSITIVE; + return ans; +} + +BigInteger BigInteger::division(const BigInteger& left, const BigInteger& right, bool is_div) { + if (right.sign == NEUTRAL) + throw std::overflow_error("Division by zero!"); + BigInteger divider = abs(right); + std::vector ans_num(left.big_number.size()); + BigInteger cur_ans; + for (int i = left.big_number.size() - 1; i >= 0; i--) { + for (int j = cur_ans.big_number.size() - 1; j > 0; j--) + cur_ans.big_number[j] = cur_ans.big_number[j - 1]; + cur_ans.clear_back(); + cur_ans.sign = POSITIVE; + cur_ans.big_number[0] = left.big_number[i]; + int div_res = 0; + int l = -1, r = MAX_VALUE + 1; + BigInteger pr_res; + while (r - l > 1) { + int m = (l + r) / 2; + pr_res = divider; + pr_res *= m; + if (pr_res > cur_ans) + r = m; + else + l = m; + } + ans_num[i] = l; + pr_res = divider; + pr_res *= l; + cur_ans -= pr_res; + cur_ans.big_number.push_back(0); + } + char ans_sign = POSITIVE; + if ((left.sign == NEGATIVE && right.sign != NEGATIVE) || (left.sign != NEGATIVE && right.sign == NEGATIVE)) + ans_sign = NEGATIVE; + BigInteger ans(ans_sign, ans_num); + ans.clear_back(); + if (is_div) + return ans; + else { + ans *= right; + return left - ans; + } +} + BigInteger operator/(const BigInteger& left, const BigInteger& right) { - //write code + return BigInteger::division(left, right, 1); } BigInteger operator%(const BigInteger& left, const BigInteger& right) { - //write code + return BigInteger::division(left, right, 0); } BigInteger& BigInteger::operator+=(const BigInteger& right) { diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index 1f1e3f64..0ac3aceb 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -46,6 +46,8 @@ class BigInteger { BigInteger& operator++(); BigInteger& operator--(); + static BigInteger abs(const BigInteger& big_num); + operator bool() const; private: @@ -56,6 +58,8 @@ class BigInteger { void clear_back(); bool check_string_to_num(const std::string& input); + static BigInteger division(const BigInteger& left, const BigInteger& right, bool is_div); + //Here will be some consts static constexpr int MAX_VALUE = 1e8; static constexpr int POS_IN_MAX_VALUE = 8; From 51475f62cca9af990ad8a84411ec3285286dcf31 Mon Sep 17 00:00:00 2001 From: Igor Egorov Date: Wed, 16 Dec 2020 15:33:08 +0300 Subject: [PATCH 5/6] Rewrote checking negativeness, positiveness, if is zero --- module-1/homework/BigInteger/biginteger.cpp | 45 +++++++++++++-------- module-1/homework/BigInteger/biginteger.h | 3 ++ 2 files changed, 32 insertions(+), 16 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp index dc2d9555..e5c381b6 100644 --- a/module-1/homework/BigInteger/biginteger.cpp +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -58,6 +58,19 @@ BigInteger::BigInteger(const std::string& num) { } } +bool BigInteger::is_negative() const { + return (this->sign == NEGATIVE); +} + +bool BigInteger::is_positive() const { + return (this->sign == POSITIVE); +} + +bool BigInteger::is_neutral() const { + return (this->sign == NEUTRAL); +} + + BigInteger::BigInteger(const char s, const std::vector& big_num) { sign = s; big_number = big_num; @@ -87,7 +100,7 @@ void BigInteger::clear() { std::string BigInteger::toString() const { std::string answer; - if (sign == NEGATIVE) + if (is_negative()) answer.push_back('-'); for (int i = big_number.size() - 1; i >= 0; i--) { if (i != big_number.size() - 1) { @@ -143,11 +156,11 @@ bool operator!=(const BigInteger& left, const BigInteger& right) { } bool operator<(const BigInteger& left, const BigInteger& right) { - if (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + if (left.is_negative() && right.is_negative()) return (-right) < (-left); - if (left.sign == BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) + if (left.is_negative() && !right.is_negative()) return true; - if (left.sign != BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + if (!left.is_negative() && right.is_negative()) return false; if (right.big_number.size() > left.big_number.size()) return true; @@ -175,19 +188,19 @@ bool operator>=(const BigInteger& left, const BigInteger& right) { } BigInteger& BigInteger::operator-() const{ - if (sign == NEGATIVE) + if (is_negative()) return *(new BigInteger(POSITIVE, big_number)); - if (sign == POSITIVE) + if (is_positive()) return *(new BigInteger(NEGATIVE, big_number)); return *(new BigInteger(NEUTRAL, big_number)); } BigInteger operator-(const BigInteger& left, const BigInteger& right) { - if (left.sign == BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) + if (left.is_negative() && !right.is_negative()) return -((-left) + right); - if (left.sign != BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + if (!left.is_negative() && right.is_negative()) return (left + (-right)); - if (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + if (left.is_negative() && right.is_negative()) return (-right) - (-left); if (right > left) return -(right - left); @@ -220,9 +233,9 @@ BigInteger operator-(const BigInteger& left, const BigInteger& right) { BigInteger operator+(const BigInteger& left, const BigInteger& right) { if (left > right) return right + left; - if (left.sign == BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) + if (left.is_negative() && !right.is_negative()) return right - (-left); - if (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE) + if (left.is_negative() && right.is_negative()) return -((-left) + (-right)); BigInteger answer; int carry = 0; @@ -246,7 +259,7 @@ BigInteger operator+(const BigInteger& left, const BigInteger& right) { } BigInteger operator*(const BigInteger& left, const BigInteger& right) { - if (left.sign == BigInteger::NEUTRAL || right.sign == BigInteger::NEUTRAL) + if (left.is_neutral() || right.is_neutral()) return BigInteger(); std::vector ans_num(left.big_number.size() + right.big_number.size()); for (size_t i = 0; i < left.big_number.size(); i++) { @@ -261,8 +274,8 @@ BigInteger operator*(const BigInteger& left, const BigInteger& right) { } } BigInteger answer = BigInteger(BigInteger::NEGATIVE, ans_num); - if ((left.sign != BigInteger::NEGATIVE && right.sign != BigInteger::NEGATIVE) || - (left.sign == BigInteger::NEGATIVE && right.sign == BigInteger::NEGATIVE)) + if ((!left.is_negative() && !right.is_negative()) || + (left.is_negative() && right.is_negative())) answer.sign = BigInteger::POSITIVE; answer.clear_back(); return answer; @@ -276,7 +289,7 @@ BigInteger BigInteger::abs(const BigInteger& big_num) { } BigInteger BigInteger::division(const BigInteger& left, const BigInteger& right, bool is_div) { - if (right.sign == NEUTRAL) + if (right.is_neutral()) throw std::overflow_error("Division by zero!"); BigInteger divider = abs(right); std::vector ans_num(left.big_number.size()); @@ -306,7 +319,7 @@ BigInteger BigInteger::division(const BigInteger& left, const BigInteger& right, cur_ans.big_number.push_back(0); } char ans_sign = POSITIVE; - if ((left.sign == NEGATIVE && right.sign != NEGATIVE) || (left.sign != NEGATIVE && right.sign == NEGATIVE)) + if ((left.is_negative() && !right.is_negative()) || (!left.is_negative() && right.is_negative())) ans_sign = NEGATIVE; BigInteger ans(ans_sign, ans_num); ans.clear_back(); diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index 0ac3aceb..67d18153 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -47,6 +47,9 @@ class BigInteger { BigInteger& operator--(); static BigInteger abs(const BigInteger& big_num); + bool is_negative() const; + bool is_positive() const; + bool is_neutral() const; operator bool() const; From 077c97feb5debbd2bd4ca24d18297014a8f0b079 Mon Sep 17 00:00:00 2001 From: Igor Egorov Date: Mon, 21 Dec 2020 03:21:03 +0300 Subject: [PATCH 6/6] Added comst modificator to methods, which are not changing any members. --- module-1/homework/BigInteger/biginteger.cpp | 2 +- module-1/homework/BigInteger/biginteger.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp index e5c381b6..cba72d7a 100644 --- a/module-1/homework/BigInteger/biginteger.cpp +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -76,7 +76,7 @@ BigInteger::BigInteger(const char s, const std::vector& big_num) { big_number = big_num; } -bool BigInteger::check_string_to_num(const std::string& input) { +bool BigInteger::check_string_to_num(const std::string& input) const { if (input.size() == 0) return 0; size_t i = 0; diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index 67d18153..bde2ee55 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -59,7 +59,7 @@ class BigInteger { char sign; void clear_back(); - bool check_string_to_num(const std::string& input); + bool check_string_to_num(const std::string& input) const; static BigInteger division(const BigInteger& left, const BigInteger& right, bool is_div);