From d6dfa23684dc5d293ef6a2aff48de5418c6f0c39 Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Fri, 11 Dec 2020 19:23:26 +0300 Subject: [PATCH 1/2] The solution of task + corrected tests --- module-1/homework/BigInteger/biginteger.cpp | 369 ++++++++++++++++++++ module-1/homework/BigInteger/biginteger.h | 107 ++++++ module-1/homework/BigInteger/tests.cpp | 5 +- 3 files changed, 478 insertions(+), 3 deletions(-) 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..00e5a063 --- /dev/null +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -0,0 +1,369 @@ +#include "biginteger.h" +#include + +BigInteger::BigInteger() { + data.push_back(0); +} + +BigInteger::BigInteger(std::vector& data, bool negative) { + if (data.empty()) + this->data = std::vector(1); + else + this->data = data; + this->is_negative = negative; +} + +BigInteger::BigInteger(const BigInteger& other) { + std::copy(other.data.begin(), other.data.end(), + std::back_inserter(data)); + this->is_negative = other.is_negative; +} + +BigInteger::BigInteger(BigInteger&& other) noexcept { + data = other.data; + is_negative = other.is_negative; + other.data = std::vector(); + other.data.push_back(0); + other.is_negative = false; +} + +BigInteger& BigInteger::operator=(const BigInteger& other) { + std::copy(other.data.begin(), other.data.end(), + std::back_inserter(data)); + this->is_negative = other.is_negative; + + return *this; +} + +BigInteger& BigInteger::operator=(BigInteger&& other) noexcept { + data = other.data; + is_negative = other.is_negative; + other.data = std::vector(); + other.data.push_back(0); + other.is_negative = false; + return *this; +} + +BigInteger::BigInteger(int num) { + while (num > 0) { + data.push_back(num % base); + num /= base; + } +} + +BigInteger BigInteger::operator-() const { + BigInteger num(*this); + num.is_negative = !is_negative; + return num; +} + +BigInteger BigInteger::operator+(const BigInteger& other) const { + if (is_negative) { + if (other.is_negative) + return -(-*this + (-other)); + else + return (other - (-*this)); + } + else + if (other.is_negative) + return *this - (-other); + std::vector new_data; + std::size_t size = std::max(data.size(), other.data.size()); + + unsigned char buffer = 0; + for (std::size_t i = 0; i < size; ++i) { + if (i >= data.size()) { + new_data.push_back(other.data[i] + buffer); + buffer = 0; + } else { + if (i >= other.data.size()) { + new_data.push_back(data[i] + buffer); + buffer = 0; + } else { + unsigned char sum = data[i] + other.data[i]; + auto elem = (sum + buffer) % base; + new_data.push_back(elem); + + buffer = (sum + buffer) / base; + } + } + + } + if (buffer > 0) + new_data.push_back(buffer); + + return BigInteger(new_data); +} + +BigInteger BigInteger::operator-(const BigInteger& other) const { + if (is_negative) { + if (other.is_negative) + return other - (-*this); + else + return -(-*this + other); + } else { + if (other.is_negative) + return *this + (-other); + } + if (*this < other) + return -(other - *this); + + unsigned char buffer = 0; + std::vector new_data; + + for (size_t i = 0; i < data.size(); ++i) { + if (i >= other.data.size()) { + if (data[i] < buffer) + new_data.push_back(base - 1); + else { + new_data.push_back(data[i] - buffer); + buffer = 0; + } + } else { + if (data[i] < other.data[i] + buffer) { + new_data.push_back(base - other.data[i] - buffer); + buffer = 1; + } else { + new_data.push_back(data[i] - other.data[i] - buffer); + buffer = 0; + } + } + } + + while ((!new_data.empty()) and new_data.back() == 0) + new_data.pop_back(); + + return BigInteger(new_data); +} + +BigInteger& BigInteger::operator+=(const BigInteger &other) { + return *this = (*this + other); +} + +BigInteger& BigInteger::operator-=(const BigInteger &other) { + return *this = (*this - other); +} + +BigInteger& BigInteger::operator++() { + *this += 1; + return *this; +} + +BigInteger BigInteger::operator++(int) { + BigInteger tmp(*this); + operator++(); + return tmp; +} + +BigInteger& BigInteger::operator--() { + *this -= 1; + return *this; +} + +BigInteger BigInteger::operator--(int) { + BigInteger tmp(*this); + operator--(); + return tmp; +} + +BigInteger BigInteger::operator*(int a) const { + std::vector new_data; + int buffer = 0; + for (size_t i = 0; i < data.size(); ++i) { + int prod = data[i] * a + buffer; + new_data.push_back(prod % base); + buffer = prod / base; + } + while (buffer > 0) { + new_data.push_back(buffer % base); + buffer /= base; + } + return BigInteger(new_data); +} + +BigInteger BigInteger::shift(size_t step) { + std::vector new_data(step, 0); + for (size_t i = 0; i < data.size(); ++i) + new_data.push_back(data[i]); + + + return BigInteger(new_data); +} + +BigInteger BigInteger::operator*(const BigInteger &other) const { + BigInteger output(0); + + for (size_t i = 0; i < other.data.size(); ++i) { + BigInteger z = (*this * (int)other.data[i]).shift(i); + output = output + z; + } + + output.is_negative = is_negative and other.is_negative; + return output; +} + +BigInteger BigInteger::operator/(const BigInteger& other) const { // error in minus operator + if (*this < other) + return BigInteger(0); + + std::vector new_data; + + BigInteger numer = *this; + BigInteger denom = other; + BigInteger curden; + + while (numer >= denom) { + int step = 0; + if (numer.data.back() < denom.data.back()) + step = 1; + + curden = denom.shift(numer.data.size() - denom.data.size() - step); + + int s = 1; + while (curden * s <= numer) + ++s; + --s; + new_data.push_back((unsigned int)s); + + numer -= curden * s; + } + + std::reverse(new_data.begin(), new_data.end()); + bool sign = is_negative and other.is_negative; + return BigInteger(new_data, sign); +} + +BigInteger BigInteger::operator%(const BigInteger &other) const { + return *this - (*this / other) * other; +} +BigInteger& BigInteger::operator*=(const BigInteger& other) { + return *this = (*this * other); +} + +BigInteger& BigInteger::operator/=(const BigInteger& other) { + return *this = (*this / other); +} + +BigInteger& BigInteger::operator%=(const BigInteger& other) { + return *this = (*this % other); +} + +bool operator==(const BigInteger& lhs, const BigInteger& rhs) { + if (lhs.data.size() != rhs.data.size()) + return false; + for (size_t i = 0; i < lhs.data.size(); ++i) + if (lhs.data[i] != rhs.data[i]) + return false; + return true; +} + +bool operator!=(const BigInteger& lhs, const BigInteger& rhs) { + return !(lhs == rhs); +} + +bool operator<(const BigInteger& lhs, const BigInteger& rhs) { + if (lhs.data.size() < rhs.data.size()) + return true; + if (lhs.data.size() > rhs.data.size()) + return false; + + size_t i = lhs.data.size(); + do { + --i; + if (lhs.data[i] < rhs.data[i]) + return true; + if (lhs.data[i] > rhs.data[i]) + return false; + } while(i != 0); + + return false; +} + +bool operator>(const BigInteger& lhs, const BigInteger& rhs) { + if (lhs.data.size() < rhs.data.size()) + return false; + if (lhs.data.size() > rhs.data.size()) + return true; + + size_t i = lhs.data.size(); + do { + --i; + if (lhs.data[i] > rhs.data[i]) + return true; + if (lhs.data[i] < rhs.data[i]) + return false; + } while(i != 0); + + return false; +} + +bool operator<=(const BigInteger& lhs, const BigInteger& rhs) { + return !(lhs > rhs); +} + +bool operator>=(const BigInteger& lhs, const BigInteger& rhs) { + return !(lhs < rhs); +} + +std::string BigInteger::toString() const { + std::string output = ""; + if (is_negative) + output = "-"; + output += std::to_string(data.back()); + + std::string suffix = ""; + + size_t i = data.size() - 1; + + if (i == 0) + return output; + + do { + i -= 1; + suffix = ""; + + if (data[i] < 10) + suffix = "0"; + suffix += std::to_string(data[i]); + + output += suffix; + + } while (i != 0); + + return output; +} + +std::ostream& operator<<(std::ostream& out, const BigInteger& obj) { + out << obj.toString(); + return out; +} + +std::istream& operator>>(std::istream& in, BigInteger& obj) { + std::string data; + in >> data; + std::string buffer = ""; + std::vector new_data; + + size_t i = data.size(); + do { + --i; + buffer = data[i] + buffer; + if (i == 0 or buffer.size() == 2) { + new_data.push_back((unsigned char)std::stoi(buffer)); + buffer = ""; + } + } while (i != 0); + + obj.data = new_data; + + return in; +} + +BigInteger::~BigInteger() { + +} + +BigInteger::operator bool() const { + return !(*this == BigInteger(0)); +} + diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h new file mode 100644 index 00000000..a47b36f0 --- /dev/null +++ b/module-1/homework/BigInteger/biginteger.h @@ -0,0 +1,107 @@ +#include +#include +#include + +class BigInteger { +public: + BigInteger(); + + BigInteger(int num); + + // to-do Конструктор копирования + // to-do Конструктор присваивания + // to-do оператор копирования + // to-do оператор присваивания + // to-do Конструирования из int + // to-do преобразование в bool + + BigInteger(const BigInteger& other); + + BigInteger(BigInteger&& other) noexcept; + + BigInteger& operator=(const BigInteger& other); + + BigInteger& operator=(BigInteger&& other) noexcept; + + BigInteger operator+(const BigInteger& other) const; + + BigInteger operator-(const BigInteger& other) const; + + BigInteger& operator+=(const BigInteger& other); + + BigInteger& operator-=(const BigInteger& other); + + BigInteger operator*(int a) const; + + BigInteger operator*(const BigInteger& other) const; + + BigInteger operator/(const BigInteger& other) const; + + BigInteger operator%(const BigInteger& other) const; + + BigInteger& operator*=(const BigInteger& other); + + BigInteger& operator/=(const BigInteger& other); + + BigInteger& operator%=(const BigInteger& other); + + BigInteger operator-() const; + + BigInteger& operator++(); + + BigInteger operator++(int); + + BigInteger& operator--(); + + BigInteger operator--(int); + + operator bool() const; + + std::string toString() const; + + ~BigInteger(); + + friend bool operator==(const BigInteger& lhs, const BigInteger& rhs); + + friend bool operator!=(const BigInteger& lhs, const BigInteger& rhs); + + friend bool operator<(const BigInteger& lhs, const BigInteger& rhs); + + friend bool operator>(const BigInteger& lhs, const BigInteger& rhs); + + friend bool operator<=(const BigInteger& lhs, const BigInteger& rhs); + + friend bool operator>=(const BigInteger& lhs, const BigInteger& rhs); + + friend std::ostream& operator<<(std::ostream& out, const BigInteger& obj); + + friend std::istream& operator>> (std::istream& in, BigInteger& obj); + +private: + BigInteger(std::vector& data, bool negative = false); + + BigInteger shift(size_t step); + +private: + std::vector data; + const unsigned char base = 100; + bool is_negative = false; +}; + +//bool operator==(const BigInteger& lhs, const BigInteger& rhs); + +//bool operator!=(const BigInteger& lhs, const BigInteger& rhs); + +//bool operator<(const BigInteger& lhs, const BigInteger& rhs); + +//bool operator>(const BigInteger& lhs, const BigInteger& rhs); + +//bool operator<=(const BigInteger& lhs, const BigInteger& rhs); + +//bool operator>=(const BigInteger& lhs, const BigInteger& rhs); + +//to-do << +//to-do >> + + + diff --git a/module-1/homework/BigInteger/tests.cpp b/module-1/homework/BigInteger/tests.cpp index 59d22015..c6118199 100644 --- a/module-1/homework/BigInteger/tests.cpp +++ b/module-1/homework/BigInteger/tests.cpp @@ -93,8 +93,7 @@ TEST(InStream, Test1) { TEST(Comparison, Test1) { - std::istringstream iss("9325492345983274589758023847509283745827349587212938129" - "348762838512387487213648172639471269348172397461297"); + std::istringstream iss("9325492345983274589758023847509283745827349587212938129 348762838512387487213648172639471269348172397461297"); BigInteger a; BigInteger b; iss >> a >> b; @@ -107,4 +106,4 @@ TEST(Comparison, Test1) { int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); -} \ No newline at end of file +} From 83f47f42ba72f2501b6d7b1f1ec6ac7590c7bb6e Mon Sep 17 00:00:00 2001 From: CardinalPrefect Date: Tue, 15 Dec 2020 12:38:06 +0300 Subject: [PATCH 2/2] Corrected notes #1 --- module-1/homework/BigInteger/biginteger.cpp | 4 ++-- module-1/homework/BigInteger/biginteger.h | 25 --------------------- 2 files changed, 2 insertions(+), 27 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.cpp b/module-1/homework/BigInteger/biginteger.cpp index 00e5a063..440cdae6 100644 --- a/module-1/homework/BigInteger/biginteger.cpp +++ b/module-1/homework/BigInteger/biginteger.cpp @@ -16,7 +16,7 @@ BigInteger::BigInteger(std::vector& data, bool negative) { BigInteger::BigInteger(const BigInteger& other) { std::copy(other.data.begin(), other.data.end(), std::back_inserter(data)); - this->is_negative = other.is_negative; + is_negative = other.is_negative; } BigInteger::BigInteger(BigInteger&& other) noexcept { @@ -30,7 +30,7 @@ BigInteger::BigInteger(BigInteger&& other) noexcept { BigInteger& BigInteger::operator=(const BigInteger& other) { std::copy(other.data.begin(), other.data.end(), std::back_inserter(data)); - this->is_negative = other.is_negative; + is_negative = other.is_negative; return *this; } diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index a47b36f0..b933300e 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -8,13 +8,6 @@ class BigInteger { BigInteger(int num); - // to-do Конструктор копирования - // to-do Конструктор присваивания - // to-do оператор копирования - // to-do оператор присваивания - // to-do Конструирования из int - // to-do преобразование в bool - BigInteger(const BigInteger& other); BigInteger(BigInteger&& other) noexcept; @@ -87,21 +80,3 @@ class BigInteger { const unsigned char base = 100; bool is_negative = false; }; - -//bool operator==(const BigInteger& lhs, const BigInteger& rhs); - -//bool operator!=(const BigInteger& lhs, const BigInteger& rhs); - -//bool operator<(const BigInteger& lhs, const BigInteger& rhs); - -//bool operator>(const BigInteger& lhs, const BigInteger& rhs); - -//bool operator<=(const BigInteger& lhs, const BigInteger& rhs); - -//bool operator>=(const BigInteger& lhs, const BigInteger& rhs); - -//to-do << -//to-do >> - - -