From 33ce4a7c72666119a5364fd9111dd5fc908c1106 Mon Sep 17 00:00:00 2001 From: GerONSo Date: Thu, 19 Nov 2020 21:08:56 +0300 Subject: [PATCH 1/4] BigInteger --- module-1/homework/BigInteger/biginteger.cpp | 0 module-1/homework/BigInteger/biginteger.h | 499 ++++++++++++++++++++ 2 files changed, 499 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..e69de29b diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h new file mode 100644 index 00000000..2d5df0ad --- /dev/null +++ b/module-1/homework/BigInteger/biginteger.h @@ -0,0 +1,499 @@ +#include +#include +#include + +struct Multiplicator { + void simple_multiply(std::vector &a, std::vector &b, std::vector &res) { + res.resize(a.size() + b.size()); + for(int i = 0; i < b.size(); i++) { + for(int j = 0; j < a.size(); j++) { + res[i + j] += b[i] * a[j]; + } + } + } + + void sum(std::vector &a, std::vector &b, std::vector &res) { + res.resize(std::max(a.size(), b.size())); + if(a.size() < b.size()) { + std::swap(a, b); + } + res = a; + for(int i = 0; i < b.size(); i++) { + res[i] += b[i]; + } + } + + void decrease(std::vector &a, std::vector &b, std::vector &res) { + res.resize(std::max(a.size(), b.size())); + res = a; + for(int i = 0; i < b.size(); i++) { + res[i] -= b[i]; + } + } + + void multiply(std::vector &a, std::vector &b, std::vector &res) { + if(std::max(a.size(), b.size()) < 100) { + simple_multiply(a, b, res); + return; + } + if(a.size() < b.size()) { + std::swap(a, b); + } + + while(b.size() < a.size()) { + b.push_back(0); + } + while((b.size() & 1)) { + a.push_back(0); + b.push_back(0); + } + int mid = a.size() / 2; + std::vector al, ar, bl, br; + for(int i = 0; i < a.size(); i++) { + if(i < mid) { + al.push_back(a[i]); + bl.push_back(b[i]); + } + else { + ar.push_back(a[i]); + br.push_back(b[i]); + } + } + std::vector r1, r2, r3, r4; + std::vector kl, kr; + sum(al, ar, kl); + sum(bl, br, kr); + multiply(al, bl, r1); + multiply(kl, kr, r2); + multiply(ar, br, r4); + reverse(r1.begin(), r1.end()); + reverse(r2.begin(), r2.end()); + reverse(r4.begin(), r4.end()); + decrease(r2, r1, r3); + decrease(r3, r4, r2); + for(int i = 0; i < mid; i++) { + r2.push_back(0); + } + for(int i = 0; i < 2 * mid; i++) { + r4.push_back(0); + } + reverse(r1.begin(), r1.end()); + reverse(r2.begin(), r2.end()); + reverse(r4.begin(), r4.end()); + sum(r1, r2, res); + std::vector res2; + sum(res, r4, res2); + res = res2; + } +}; + +class BigInteger { + private: + std::vector base; + bool negative = 0; + + public: + + BigInteger() = default; + + BigInteger(int a) { + if(a < 0) { + negative = 1; + } + a = abs(a); + base.clear(); + while(a != 0) { + base.push_back(a % 10); + a /= 10; + } + } + + void operator=(int a) { + if(a < 0) { + negative = 1; + } + a = abs(a); + base.clear(); + while(a != 0) { + base.push_back(a % 10); + a /= 10; + } + } + + BigInteger& operator+= (BigInteger int2) { + BigInteger nw = *this + int2; + base = nw.base; + negative = nw.negative; + return *this; + } + + BigInteger& operator-= (BigInteger int2) { + BigInteger nw = *this - int2; + base = nw.base; + negative = nw.negative; + return *this; + } + + BigInteger& operator*= (BigInteger int2) { + BigInteger nw = *this * int2; + base = nw.base; + negative = nw.negative; + return *this; + } + + BigInteger& operator/= (BigInteger int2) { + BigInteger nw = *this / int2; + base = nw.base; + negative = nw.negative; + return *this; + } + + BigInteger& operator%= (BigInteger int2) { + BigInteger nw = *this % int2; + base = nw.base; + negative = nw.negative; + return *this; + } + + BigInteger operator- () { + negative = !negative; + return *this; + } + + BigInteger operator+ (BigInteger int2) { + int next = 0; + BigInteger answer; + BigInteger a = *this; + BigInteger b = int2; + if(a.negative == false && b.negative == false) { + answer.negative = false; + } + else if(a.negative == true && b.negative == false) { + a.negative = false; + answer = b - a; + return answer; + } + else if(a.negative == false && b.negative == true) { + b.negative = false; + answer = a - b; + return answer; + } + else { + answer.negative = true; + } + if(a < b) { + std::swap(a, b); + } + for(int i = 0; i < a.base.size(); i++) { + if(i < b.base.size()) { + int num = a.base[i] + b.base[i] + next; + answer.base.push_back(num % 10); + next = (num / 10) % 10; + } + else { + answer.base.push_back(a.base[i] + next); + next = 0; + } + } + if(next != 0) { + answer.base.push_back(next); + } + return answer; + } + + + + BigInteger operator- (BigInteger int2) { + BigInteger answer; + BigInteger a = *this; + BigInteger b = int2; + if(a.negative == false && b.negative == false) { + answer.negative = false; + } + else if(a.negative == true && b.negative == false) { + a.negative = false; + answer = a + b; + answer.negative = true; + return answer; + } + else if(a.negative == false && b.negative == true) { + b.negative = false; + answer = a + b; + answer.negative = false; + return answer; + } + else { + std::swap(a, b); + answer.negative = false; + } + int inverse = 0; + if(a < b) { + std::swap(a, b); + inverse = 1; + } + int add = 0; + for(int i = 0; i < a.base.size(); i++) { + if(i < b.base.size()) { + if(a.base[i] - add >= b.base[i]) { + answer.base.push_back(a.base[i] - add - b.base[i]); + // std::cerr << a.base[i] - add - b.base[i]; + } + else { + answer.base.push_back(a.base[i] - add - b.base[i] + 10); + // std::cerr << a.base[i] - add - b.base[i] + 10; + add = 1; + } + } + else { + if(a.base[i] >= add) { + answer.base.push_back(a.base[i] - add); + add = 0; + } + else { + answer.base.push_back(10 - add); + add = 1; + } + } + } + while(answer.base.size() && answer.base.back() == 0) { + answer.base.pop_back(); + } + if(answer.base.size() == 0) { + answer.base.push_back(0); + } + answer.negative ^= inverse; + return answer; + } + + BigInteger operator* (BigInteger int2) { + BigInteger a = *this; + BigInteger b = int2; + BigInteger answer; + Multiplicator multiplicator; + multiplicator.multiply(a.base, b.base, answer.base); + if(a.negative ^ b.negative) { + answer.negative = true; + } + else { + answer.negative = false; + } + for(int i = 0; i < answer.base.size() - 1; i++) { + if(i < answer.base.size() - 1) { + answer.base[i + 1] += answer.base[i] / 10; + answer.base[i] %= 10; + } + } + while(answer.base.back() != 0) { + int cnt = answer.base.back(); + answer.base[answer.base.size() - 1] %= 10; + answer.base.push_back(cnt / 10); + + } + while(answer.base.size() && answer.base.back() == 0) { + answer.base.pop_back(); + } + if(answer.base.size() == 0) { + answer.base.push_back(0); + } + return answer; + } + + BigInteger operator/ (BigInteger int2) { + BigInteger a = *this; + BigInteger b = int2; + BigInteger answer; + if(a.negative ^ b.negative) { + answer.negative = true; + } + else { + answer.negative = false; + } + a.negative = false; + b.negative = false; + int pos = a.base.size() - 1; + BigInteger cur = 0; + while(pos >= 0) { + cur = cur * BigInteger(10) + BigInteger(a.base[pos]); + pos--; + if(cur >= b) { + int num; + for(int i = 0; i < 10; i++) { + if(b * BigInteger(i) > cur) { + num = i - 1; + break; + } + } + BigInteger bigNum = num; + cur = cur - (b * bigNum); + answer.base.push_back(num); + } + else { + answer.base.push_back(0); + } + } + reverse(answer.base.begin(), answer.base.end()); + while(answer.base.size() && answer.base.back() == 0) { + answer.base.pop_back(); + } + if(answer.base.size() == 0) { + answer.base.push_back(0); + } + return answer; + } + + BigInteger operator% (BigInteger int2) { + BigInteger a = *this; + BigInteger b = int2; + BigInteger answer = a; + bool negative = a.negative; + b.negative = false; + int pos = a.base.size() - 1; + BigInteger cur = 0; + while(pos >= 0) { + cur = cur * BigInteger(10) + BigInteger(a.base[pos]); + pos--; + if(cur >= b) { + int num; + for(int i = 0; i < 10; i++) { + if(b * BigInteger(i) > cur) { + num = i - 1; + break; + } + } + BigInteger bigNum = num; + cur = cur - (b * bigNum); + answer = cur; + } + } + answer.negative = negative; + return answer; + } + + bool operator== (BigInteger int2) { + if(base.size() != int2.base.size()) { + return false; + } + for(int i = 0; i < base.size(); i++) { + if(base[i] != int2.base[i]) { + return false; + } + } + return true; + } + + bool operator!= (BigInteger int2) { + return !(*this == int2); + } + + bool operator< (BigInteger int2) { + if(base.size() < int2.base.size()) { + return true; + } + if(base.size() > int2.base.size()) { + return false; + } + for(int i = base.size() - 1; i >= 0; i--) { + if(base[i] < int2.base[i]) { + return true; + } + if(base[i] > int2.base[i]) { + return false; + } + } + return false; + } + + bool operator> (BigInteger int2) { + return !(*this < int2) && *this != int2; + } + + bool operator<= (BigInteger int2) { + return !(*this > int2); + } + + bool operator>= (BigInteger int2) { + return !(*this < int2); + } + + BigInteger& operator++() { + *this = *this + BigInteger(1); + if(*this >= BigInteger(0)) { + this->negative = false; + } + return *this; + } + + BigInteger operator++(int) { + BigInteger current = *this; + ++*this; + if(*this >= BigInteger(0)) { + this->negative = false; + } + return current; + } + + operator bool() const { + return !(*this == 0); + } + + std::string toString() { + std::string ans = ""; + for(int i : base) { + ans += (i + '0'); + } + reverse(ans.begin(), ans.end()); + return ans; + } + + std::vector getBase() { + return base; + } + + bool getNegative() { + return negative; + } + + // Could be overflow + int toInt() { + int ans = 0; + int pw = 1; + for(int i = 0; i < base.size(); i++) { + ans += base[i] * pw; + pw *= 10; + } + return ans; + } + + friend std::ostringstream& operator<<(std::ostringstream& os, BigInteger &integer); + + friend std::ostream& operator<<(std::ostream& os, BigInteger integer); + +}; + +std::ostringstream& operator<<(std::ostringstream& os, BigInteger &integer) { + os << ((integer.getNegative()) ? "-" : ""); + for(int i = integer.getBase().size() - 1; i >= 0; i--) { + os << integer.getBase()[i]; + } + return os; +} + +std::ostream& operator<<(std::ostream& os, BigInteger integer) { + os << ((integer.getNegative()) ? "-" : ""); + for(int i = integer.getBase().size() - 1; i >= 0; i--) { + os << integer.getBase()[i]; + } + return os; +} + +std::istringstream& operator>>(std::istringstream& is, BigInteger &integer) { + std::string s; + is >> s; + return is; +} + +std::istream& operator>>(std::istream& is, BigInteger integer) { + std::string s; + is >> s; + return is; +} \ No newline at end of file From 5c5a663b8db83b6d5ea097b14508058cedbc4f0d Mon Sep 17 00:00:00 2001 From: GerONSo Date: Fri, 20 Nov 2020 00:16:45 +0300 Subject: [PATCH 2/4] BigInteger pt.2 --- module-1/homework/BigInteger/biginteger.h | 69 +++++++++++++++-------- 1 file changed, 45 insertions(+), 24 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index 2d5df0ad..a6661f9c 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -88,12 +88,10 @@ struct Multiplicator { }; class BigInteger { - private: + public: std::vector base; bool negative = 0; - public: - BigInteger() = default; BigInteger(int a) { @@ -236,11 +234,9 @@ class BigInteger { if(i < b.base.size()) { if(a.base[i] - add >= b.base[i]) { answer.base.push_back(a.base[i] - add - b.base[i]); - // std::cerr << a.base[i] - add - b.base[i]; } else { answer.base.push_back(a.base[i] - add - b.base[i] + 10); - // std::cerr << a.base[i] - add - b.base[i] + 10; add = 1; } } @@ -369,23 +365,11 @@ class BigInteger { return answer; } - bool operator== (BigInteger int2) { - if(base.size() != int2.base.size()) { - return false; - } - for(int i = 0; i < base.size(); i++) { - if(base[i] != int2.base[i]) { - return false; - } - } - return true; - } - bool operator!= (BigInteger int2) { return !(*this == int2); } - bool operator< (BigInteger int2) { + bool isLess(BigInteger int2) { if(base.size() < int2.base.size()) { return true; } @@ -403,6 +387,21 @@ class BigInteger { return false; } + bool operator< (BigInteger int2) { + if(*this == BigInteger(0)) { + negative = false; + } + if(int2 == BigInteger(0)) { + int2.negative = false; + } + if(negative != int2.negative) { + return ((negative) ? true : false); + } + else { + return (isLess(int2) != negative); + } + } + bool operator> (BigInteger int2) { return !(*this < int2) && *this != int2; } @@ -433,7 +432,8 @@ class BigInteger { } operator bool() const { - return !(*this == 0); + std::cerr << *this << '\n'; + return !(BigInteger(*this) == BigInteger(0)); } std::string toString() { @@ -468,8 +468,30 @@ class BigInteger { friend std::ostream& operator<<(std::ostream& os, BigInteger integer); + friend std::istringstream& operator>>(std::istringstream& is, BigInteger &integer); + + friend bool operator== (BigInteger int1, BigInteger int2); + }; +bool operator== (BigInteger int1, BigInteger int2) { + if(int1.getBase().size() != int2.getBase().size()) { + return false; + } + if(int1.getBase().size() == 1 && int1.getBase()[0] == 0 && int2.getBase()[0] == 0) { + return true; + } + if(int1.getNegative() != int2.getNegative()) { + return false; + } + for(int i = 0; i < int1.getBase().size(); i++) { + if(int1.getBase()[i] != int2.getBase()[i]) { + return false; + } + } + return true; +} + std::ostringstream& operator<<(std::ostringstream& os, BigInteger &integer) { os << ((integer.getNegative()) ? "-" : ""); for(int i = integer.getBase().size() - 1; i >= 0; i--) { @@ -487,13 +509,12 @@ std::ostream& operator<<(std::ostream& os, BigInteger integer) { } std::istringstream& operator>>(std::istringstream& is, BigInteger &integer) { + integer.base.clear(); std::string s; is >> s; + for(int i = s.size() - 1; i >= 0; i--) { + integer.base.push_back(s[i] - '0'); + } return is; } -std::istream& operator>>(std::istream& is, BigInteger integer) { - std::string s; - is >> s; - return is; -} \ No newline at end of file From 4ad803525879ebd64535fff219f34191495966b9 Mon Sep 17 00:00:00 2001 From: GerONSo Date: Mon, 23 Nov 2020 17:13:27 +0300 Subject: [PATCH 3/4] Fixed BigInteger --- module-1/homework/BigInteger/biginteger.h | 217 ++++++++++++++-------- 1 file changed, 136 insertions(+), 81 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index a6661f9c..64489163 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -3,39 +3,35 @@ #include struct Multiplicator { - void simple_multiply(std::vector &a, std::vector &b, std::vector &res) { + void simple_multiply(std::vector& a, std::vector& b, std::vector& res) { res.resize(a.size() + b.size()); - for(int i = 0; i < b.size(); i++) { - for(int j = 0; j < a.size(); j++) { + for(std::size_t i = 0; i < b.size(); i++) { + for(std::size_t j = 0; j < a.size(); j++) { res[i + j] += b[i] * a[j]; } } } - void sum(std::vector &a, std::vector &b, std::vector &res) { + void sum(std::vector& a, std::vector& b, std::vector& res) { res.resize(std::max(a.size(), b.size())); if(a.size() < b.size()) { std::swap(a, b); } res = a; - for(int i = 0; i < b.size(); i++) { + for(std::size_t i = 0; i < b.size(); i++) { res[i] += b[i]; } } - void decrease(std::vector &a, std::vector &b, std::vector &res) { + void decrease(std::vector& a, std::vector& b, std::vector& res) { res.resize(std::max(a.size(), b.size())); res = a; - for(int i = 0; i < b.size(); i++) { + for(std::size_t i = 0; i < b.size(); i++) { res[i] -= b[i]; } } - - void multiply(std::vector &a, std::vector &b, std::vector &res) { - if(std::max(a.size(), b.size()) < 100) { - simple_multiply(a, b, res); - return; - } + + void prepareNumbers(std::vector& a, std::vector& b, std::vector& res) { if(a.size() < b.size()) { std::swap(a, b); } @@ -47,9 +43,12 @@ struct Multiplicator { a.push_back(0); b.push_back(0); } - int mid = a.size() / 2; - std::vector al, ar, bl, br; - for(int i = 0; i < a.size(); i++) { + } + + void split(std::vector& al, std::vector& ar, + std::vector& bl, std::vector& br, + std::vector& a, std::vector& b, int mid) { + for(std::size_t i = 0; i < a.size(); i++) { if(i < mid) { al.push_back(a[i]); bl.push_back(b[i]); @@ -59,27 +58,61 @@ struct Multiplicator { br.push_back(b[i]); } } - std::vector r1, r2, r3, r4; - std::vector kl, kr; - sum(al, ar, kl); - sum(bl, br, kr); - multiply(al, bl, r1); - multiply(kl, kr, r2); - multiply(ar, br, r4); + } + + void reverseParts(std::vector& r1, std::vector& r2, std::vector& r4) { reverse(r1.begin(), r1.end()); reverse(r2.begin(), r2.end()); reverse(r4.begin(), r4.end()); + } + + void multiplyParts(std::vector& r1, std::vector& r2, + std::vector& r4, std::vector& al, + std::vector& bl, std::vector& kl, + std::vector& kr, std::vector& ar, + std::vector& br) { + multiply(al, bl, r1); + multiply(kl, kr, r2); + multiply(ar, br, r4); + } + + void sumParts(std::vector& al, std::vector& bl, + std::vector& kl, std::vector& kr, + std::vector& ar, std::vector& br) { + sum(al, ar, kl); + sum(bl, br, kr); + } + + void multiply(std::vector& a, std::vector& b, std::vector& res) { + if(std::max(a.size(), b.size()) < 100) { + simple_multiply(a, b, res); + return; + } + prepareNumbers(a, b, res); + int mid = a.size() / 2; + std::vector al; + std::vector ar; + std::vector bl; + std::vector br; + split(al, ar, bl, br, a, b, mid); + std::vector r1; + std::vector r2; + std::vector r3; + std::vector r4; + std::vector kl; + std::vector kr; + sumParts(al, bl, kl, kr, ar, br); + multiplyParts(r1, r2, r4, al, bl, kl, kr, ar, br); + reverseParts(r1, r2, r4); decrease(r2, r1, r3); decrease(r3, r4, r2); - for(int i = 0; i < mid; i++) { + for(std::size_t i = 0; i < mid; i++) { r2.push_back(0); } - for(int i = 0; i < 2 * mid; i++) { + for(std::size_t i = 0; i < 2 * mid; i++) { r4.push_back(0); } - reverse(r1.begin(), r1.end()); - reverse(r2.begin(), r2.end()); - reverse(r4.begin(), r4.end()); + reverseParts(r1, r2, r4); sum(r1, r2, res); std::vector res2; sum(res, r4, res2); @@ -88,9 +121,10 @@ struct Multiplicator { }; class BigInteger { - public: + private: std::vector base; bool negative = 0; + public: BigInteger() = default; @@ -106,7 +140,7 @@ class BigInteger { } } - void operator=(int a) { + BigInteger& operator=(int a) { if(a < 0) { negative = 1; } @@ -118,35 +152,35 @@ class BigInteger { } } - BigInteger& operator+= (BigInteger int2) { + BigInteger& operator+= (const BigInteger& int2) { BigInteger nw = *this + int2; base = nw.base; negative = nw.negative; return *this; } - BigInteger& operator-= (BigInteger int2) { + BigInteger& operator-= (const BigInteger& int2) { BigInteger nw = *this - int2; base = nw.base; negative = nw.negative; return *this; } - BigInteger& operator*= (BigInteger int2) { + BigInteger& operator*= (const BigInteger& int2) { BigInteger nw = *this * int2; base = nw.base; negative = nw.negative; return *this; } - BigInteger& operator/= (BigInteger int2) { + BigInteger& operator/= (const BigInteger& int2) { BigInteger nw = *this / int2; base = nw.base; negative = nw.negative; return *this; } - BigInteger& operator%= (BigInteger int2) { + BigInteger& operator%= (const BigInteger& int2) { BigInteger nw = *this % int2; base = nw.base; negative = nw.negative; @@ -158,7 +192,7 @@ class BigInteger { return *this; } - BigInteger operator+ (BigInteger int2) { + BigInteger operator+ (const BigInteger& int2) { int next = 0; BigInteger answer; BigInteger a = *this; @@ -166,12 +200,12 @@ class BigInteger { if(a.negative == false && b.negative == false) { answer.negative = false; } - else if(a.negative == true && b.negative == false) { + else if(a.negative && !b.negative) { a.negative = false; answer = b - a; return answer; } - else if(a.negative == false && b.negative == true) { + else if(!a.negative && b.negative) { b.negative = false; answer = a - b; return answer; @@ -182,7 +216,7 @@ class BigInteger { if(a < b) { std::swap(a, b); } - for(int i = 0; i < a.base.size(); i++) { + for(std::size_t i = 0; i < a.base.size(); i++) { if(i < b.base.size()) { int num = a.base[i] + b.base[i] + next; answer.base.push_back(num % 10); @@ -201,20 +235,20 @@ class BigInteger { - BigInteger operator- (BigInteger int2) { + BigInteger operator- (const BigInteger& int2) { BigInteger answer; BigInteger a = *this; BigInteger b = int2; if(a.negative == false && b.negative == false) { answer.negative = false; } - else if(a.negative == true && b.negative == false) { + else if(a.negative && !b.negative) { a.negative = false; answer = a + b; answer.negative = true; return answer; } - else if(a.negative == false && b.negative == true) { + else if(!a.negative && b.negative) { b.negative = false; answer = a + b; answer.negative = false; @@ -230,7 +264,7 @@ class BigInteger { inverse = 1; } int add = 0; - for(int i = 0; i < a.base.size(); i++) { + for(std::size_t i = 0; i < a.base.size(); i++) { if(i < b.base.size()) { if(a.base[i] - add >= b.base[i]) { answer.base.push_back(a.base[i] - add - b.base[i]); @@ -261,7 +295,7 @@ class BigInteger { return answer; } - BigInteger operator* (BigInteger int2) { + BigInteger operator* (const BigInteger& int2) { BigInteger a = *this; BigInteger b = int2; BigInteger answer; @@ -273,7 +307,7 @@ class BigInteger { else { answer.negative = false; } - for(int i = 0; i < answer.base.size() - 1; i++) { + for(std::size_t i = 0; i < answer.base.size() - 1; i++) { if(i < answer.base.size() - 1) { answer.base[i + 1] += answer.base[i] / 10; answer.base[i] %= 10; @@ -294,7 +328,7 @@ class BigInteger { return answer; } - BigInteger operator/ (BigInteger int2) { + BigInteger operator/ (const BigInteger& int2) { BigInteger a = *this; BigInteger b = int2; BigInteger answer; @@ -337,7 +371,7 @@ class BigInteger { return answer; } - BigInteger operator% (BigInteger int2) { + BigInteger operator% (const BigInteger& int2) { BigInteger a = *this; BigInteger b = int2; BigInteger answer = a; @@ -365,59 +399,63 @@ class BigInteger { return answer; } - bool operator!= (BigInteger int2) { + bool operator!= (const BigInteger& int2) { return !(*this == int2); } - bool isLess(BigInteger int2) { + bool isLess(const BigInteger& int2) { if(base.size() < int2.base.size()) { return true; } if(base.size() > int2.base.size()) { return false; } - for(int i = base.size() - 1; i >= 0; i--) { + for(std::size_t i = base.size() - 1; i >= 0; i--) { if(base[i] < int2.base[i]) { return true; } if(base[i] > int2.base[i]) { return false; } + if(i == 0) { + break; + } } return false; } - bool operator< (BigInteger int2) { + bool operator< (const BigInteger& int2) { + BigInteger int2Copy = int2; if(*this == BigInteger(0)) { negative = false; } if(int2 == BigInteger(0)) { - int2.negative = false; + int2Copy.negative = false; } - if(negative != int2.negative) { + if(negative != int2Copy.negative) { return ((negative) ? true : false); } else { - return (isLess(int2) != negative); + return (isLess(int2Copy) != negative); } } - bool operator> (BigInteger int2) { + bool operator> (const BigInteger& int2) { return !(*this < int2) && *this != int2; } - bool operator<= (BigInteger int2) { + bool operator<= (const BigInteger& int2) { return !(*this > int2); } - bool operator>= (BigInteger int2) { + bool operator>= (const BigInteger& int2) { return !(*this < int2); } BigInteger& operator++() { *this = *this + BigInteger(1); if(*this >= BigInteger(0)) { - this->negative = false; + negative = false; } return *this; } @@ -426,13 +464,12 @@ class BigInteger { BigInteger current = *this; ++*this; if(*this >= BigInteger(0)) { - this->negative = false; + negative = false; } return current; } operator bool() const { - std::cerr << *this << '\n'; return !(BigInteger(*this) == BigInteger(0)); } @@ -445,11 +482,11 @@ class BigInteger { return ans; } - std::vector getBase() { + std::vector getBase() const { return base; } - bool getNegative() { + bool getNegative() const { return negative; } @@ -457,58 +494,77 @@ class BigInteger { int toInt() { int ans = 0; int pw = 1; - for(int i = 0; i < base.size(); i++) { + for(std::size_t i = 0; i < base.size(); i++) { ans += base[i] * pw; pw *= 10; } return ans; } - friend std::ostringstream& operator<<(std::ostringstream& os, BigInteger &integer); + friend std::ostringstream& operator<<(std::ostringstream& os, const BigInteger& integer); - friend std::ostream& operator<<(std::ostream& os, BigInteger integer); + friend std::ostream& operator<<(std::ostream& os, const BigInteger& integer); - friend std::istringstream& operator>>(std::istringstream& is, BigInteger &integer); + friend std::istringstream& operator>>(std::istringstream& is, BigInteger& integer); - friend bool operator== (BigInteger int1, BigInteger int2); + friend bool operator== (const BigInteger& int1, const BigInteger& int2); }; -bool operator== (BigInteger int1, BigInteger int2) { - if(int1.getBase().size() != int2.getBase().size()) { +bool checkDifferentSignsZeros(const std::vector& base1, const std::vector& base2) { + if(base1.size() == 1 && base1[0] == 0 && base2[0] == 0) { + return true; + } + else { + return false; + } +} + +bool operator== (const BigInteger& int1, const BigInteger& int2) { + std::vector base1 = int1.getBase(); + std::vector base2 = int2.getBase(); + if(base1.size() != base2.size()) { return false; } - if(int1.getBase().size() == 1 && int1.getBase()[0] == 0 && int2.getBase()[0] == 0) { + if(checkDifferentSignsZeros(base1, base2)) { return true; } if(int1.getNegative() != int2.getNegative()) { return false; } - for(int i = 0; i < int1.getBase().size(); i++) { - if(int1.getBase()[i] != int2.getBase()[i]) { + for(std::size_t i = 0; i < base1.size(); i++) { + if(base1[i] != base2[i]) { return false; } } return true; } -std::ostringstream& operator<<(std::ostringstream& os, BigInteger &integer) { +std::ostringstream& operator<<(std::ostringstream& os, const BigInteger& integer) { os << ((integer.getNegative()) ? "-" : ""); - for(int i = integer.getBase().size() - 1; i >= 0; i--) { - os << integer.getBase()[i]; + std::vector base = integer.getBase(); + for(std::size_t i = base.size() - 1; i >= 0; i--) { + os << base[i]; + if(i == 0) { + break; + } } return os; } -std::ostream& operator<<(std::ostream& os, BigInteger integer) { +std::ostream& operator<<(std::ostream& os, const BigInteger& integer) { os << ((integer.getNegative()) ? "-" : ""); - for(int i = integer.getBase().size() - 1; i >= 0; i--) { - os << integer.getBase()[i]; + std::vector base = integer.getBase(); + for(std::size_t i = base.size() - 1; i >= 0; i--) { + os << base[i]; + if(i == 0) { + break; + } } return os; } -std::istringstream& operator>>(std::istringstream& is, BigInteger &integer) { +std::istringstream& operator>>(std::istringstream& is, BigInteger& integer) { integer.base.clear(); std::string s; is >> s; @@ -516,5 +572,4 @@ std::istringstream& operator>>(std::istringstream& is, BigInteger &integer) { integer.base.push_back(s[i] - '0'); } return is; -} - +} \ No newline at end of file From f59c27b50c9bca3c9e10f1c1236cb016e06ab960 Mon Sep 17 00:00:00 2001 From: GerONSo Date: Wed, 9 Dec 2020 19:32:46 +0300 Subject: [PATCH 4/4] Updated BigInteger --- module-1/homework/BigInteger/biginteger.h | 620 +++++++++++----------- 1 file changed, 322 insertions(+), 298 deletions(-) diff --git a/module-1/homework/BigInteger/biginteger.h b/module-1/homework/BigInteger/biginteger.h index 64489163..6ae197c4 100644 --- a/module-1/homework/BigInteger/biginteger.h +++ b/module-1/homework/BigInteger/biginteger.h @@ -60,20 +60,20 @@ struct Multiplicator { } } - void reverseParts(std::vector& r1, std::vector& r2, std::vector& r4) { - reverse(r1.begin(), r1.end()); - reverse(r2.begin(), r2.end()); - reverse(r4.begin(), r4.end()); + void reverseParts(std::vector& leftToLeftComposition, std::vector& sumToSumComposition, std::vector& rightToRightComposition) { + reverse(leftToLeftComposition.begin(), leftToLeftComposition.end()); + reverse(sumToSumComposition.begin(), sumToSumComposition.end()); + reverse(rightToRightComposition.begin(), rightToRightComposition.end()); } - void multiplyParts(std::vector& r1, std::vector& r2, - std::vector& r4, std::vector& al, + void multiplyParts(std::vector& leftToLeftComposition, std::vector& sumToSumComposition, + std::vector& rightToRightComposition, std::vector& al, std::vector& bl, std::vector& kl, std::vector& kr, std::vector& ar, std::vector& br) { - multiply(al, bl, r1); - multiply(kl, kr, r2); - multiply(ar, br, r4); + multiply(al, bl, leftToLeftComposition); + multiply(kl, kr, sumToSumComposition); + multiply(ar, br, rightToRightComposition); } void sumParts(std::vector& al, std::vector& bl, @@ -95,27 +95,27 @@ struct Multiplicator { std::vector bl; std::vector br; split(al, ar, bl, br, a, b, mid); - std::vector r1; - std::vector r2; - std::vector r3; - std::vector r4; + std::vector leftToLeftComposition; + std::vector sumToSumComposition; + std::vector sumToLeftDifference; + std::vector rightToRightComposition; std::vector kl; std::vector kr; sumParts(al, bl, kl, kr, ar, br); - multiplyParts(r1, r2, r4, al, bl, kl, kr, ar, br); - reverseParts(r1, r2, r4); - decrease(r2, r1, r3); - decrease(r3, r4, r2); + multiplyParts(leftToLeftComposition, sumToSumComposition, rightToRightComposition, al, bl, kl, kr, ar, br); + reverseParts(leftToLeftComposition, sumToSumComposition, rightToRightComposition); + decrease(sumToSumComposition, leftToLeftComposition, sumToLeftDifference); + decrease(sumToLeftDifference, rightToRightComposition, sumToSumComposition); for(std::size_t i = 0; i < mid; i++) { - r2.push_back(0); + sumToSumComposition.push_back(0); } for(std::size_t i = 0; i < 2 * mid; i++) { - r4.push_back(0); + rightToRightComposition.push_back(0); } - reverseParts(r1, r2, r4); - sum(r1, r2, res); + reverseParts(leftToLeftComposition, sumToSumComposition, rightToRightComposition); + sum(leftToLeftComposition, sumToSumComposition, res); std::vector res2; - sum(res, r4, res2); + sum(res, rightToRightComposition, res2); res = res2; } }; @@ -132,30 +132,44 @@ class BigInteger { if(a < 0) { negative = 1; } + base.clear(); + if(a == 0) { + base.push_back(0); + return; + } a = abs(a); base.clear(); while(a != 0) { base.push_back(a % 10); a /= 10; } + normalizeZero(); } BigInteger& operator=(int a) { if(a < 0) { negative = 1; } + base.clear(); + if(a == 0) { + base.push_back(0); + return *this; + } a = abs(a); base.clear(); while(a != 0) { base.push_back(a % 10); a /= 10; } + return *this; + normalizeZero(); } BigInteger& operator+= (const BigInteger& int2) { BigInteger nw = *this + int2; base = nw.base; negative = nw.negative; + normalizeZero(); return *this; } @@ -163,6 +177,7 @@ class BigInteger { BigInteger nw = *this - int2; base = nw.base; negative = nw.negative; + normalizeZero(); return *this; } @@ -170,6 +185,7 @@ class BigInteger { BigInteger nw = *this * int2; base = nw.base; negative = nw.negative; + normalizeZero(); return *this; } @@ -177,6 +193,7 @@ class BigInteger { BigInteger nw = *this / int2; base = nw.base; negative = nw.negative; + normalizeZero(); return *this; } @@ -184,274 +201,16 @@ class BigInteger { BigInteger nw = *this % int2; base = nw.base; negative = nw.negative; + normalizeZero(); return *this; } BigInteger operator- () { negative = !negative; + normalizeZero(); return *this; } - BigInteger operator+ (const BigInteger& int2) { - int next = 0; - BigInteger answer; - BigInteger a = *this; - BigInteger b = int2; - if(a.negative == false && b.negative == false) { - answer.negative = false; - } - else if(a.negative && !b.negative) { - a.negative = false; - answer = b - a; - return answer; - } - else if(!a.negative && b.negative) { - b.negative = false; - answer = a - b; - return answer; - } - else { - answer.negative = true; - } - if(a < b) { - std::swap(a, b); - } - for(std::size_t i = 0; i < a.base.size(); i++) { - if(i < b.base.size()) { - int num = a.base[i] + b.base[i] + next; - answer.base.push_back(num % 10); - next = (num / 10) % 10; - } - else { - answer.base.push_back(a.base[i] + next); - next = 0; - } - } - if(next != 0) { - answer.base.push_back(next); - } - return answer; - } - - - - BigInteger operator- (const BigInteger& int2) { - BigInteger answer; - BigInteger a = *this; - BigInteger b = int2; - if(a.negative == false && b.negative == false) { - answer.negative = false; - } - else if(a.negative && !b.negative) { - a.negative = false; - answer = a + b; - answer.negative = true; - return answer; - } - else if(!a.negative && b.negative) { - b.negative = false; - answer = a + b; - answer.negative = false; - return answer; - } - else { - std::swap(a, b); - answer.negative = false; - } - int inverse = 0; - if(a < b) { - std::swap(a, b); - inverse = 1; - } - int add = 0; - for(std::size_t i = 0; i < a.base.size(); i++) { - if(i < b.base.size()) { - if(a.base[i] - add >= b.base[i]) { - answer.base.push_back(a.base[i] - add - b.base[i]); - } - else { - answer.base.push_back(a.base[i] - add - b.base[i] + 10); - add = 1; - } - } - else { - if(a.base[i] >= add) { - answer.base.push_back(a.base[i] - add); - add = 0; - } - else { - answer.base.push_back(10 - add); - add = 1; - } - } - } - while(answer.base.size() && answer.base.back() == 0) { - answer.base.pop_back(); - } - if(answer.base.size() == 0) { - answer.base.push_back(0); - } - answer.negative ^= inverse; - return answer; - } - - BigInteger operator* (const BigInteger& int2) { - BigInteger a = *this; - BigInteger b = int2; - BigInteger answer; - Multiplicator multiplicator; - multiplicator.multiply(a.base, b.base, answer.base); - if(a.negative ^ b.negative) { - answer.negative = true; - } - else { - answer.negative = false; - } - for(std::size_t i = 0; i < answer.base.size() - 1; i++) { - if(i < answer.base.size() - 1) { - answer.base[i + 1] += answer.base[i] / 10; - answer.base[i] %= 10; - } - } - while(answer.base.back() != 0) { - int cnt = answer.base.back(); - answer.base[answer.base.size() - 1] %= 10; - answer.base.push_back(cnt / 10); - - } - while(answer.base.size() && answer.base.back() == 0) { - answer.base.pop_back(); - } - if(answer.base.size() == 0) { - answer.base.push_back(0); - } - return answer; - } - - BigInteger operator/ (const BigInteger& int2) { - BigInteger a = *this; - BigInteger b = int2; - BigInteger answer; - if(a.negative ^ b.negative) { - answer.negative = true; - } - else { - answer.negative = false; - } - a.negative = false; - b.negative = false; - int pos = a.base.size() - 1; - BigInteger cur = 0; - while(pos >= 0) { - cur = cur * BigInteger(10) + BigInteger(a.base[pos]); - pos--; - if(cur >= b) { - int num; - for(int i = 0; i < 10; i++) { - if(b * BigInteger(i) > cur) { - num = i - 1; - break; - } - } - BigInteger bigNum = num; - cur = cur - (b * bigNum); - answer.base.push_back(num); - } - else { - answer.base.push_back(0); - } - } - reverse(answer.base.begin(), answer.base.end()); - while(answer.base.size() && answer.base.back() == 0) { - answer.base.pop_back(); - } - if(answer.base.size() == 0) { - answer.base.push_back(0); - } - return answer; - } - - BigInteger operator% (const BigInteger& int2) { - BigInteger a = *this; - BigInteger b = int2; - BigInteger answer = a; - bool negative = a.negative; - b.negative = false; - int pos = a.base.size() - 1; - BigInteger cur = 0; - while(pos >= 0) { - cur = cur * BigInteger(10) + BigInteger(a.base[pos]); - pos--; - if(cur >= b) { - int num; - for(int i = 0; i < 10; i++) { - if(b * BigInteger(i) > cur) { - num = i - 1; - break; - } - } - BigInteger bigNum = num; - cur = cur - (b * bigNum); - answer = cur; - } - } - answer.negative = negative; - return answer; - } - - bool operator!= (const BigInteger& int2) { - return !(*this == int2); - } - - bool isLess(const BigInteger& int2) { - if(base.size() < int2.base.size()) { - return true; - } - if(base.size() > int2.base.size()) { - return false; - } - for(std::size_t i = base.size() - 1; i >= 0; i--) { - if(base[i] < int2.base[i]) { - return true; - } - if(base[i] > int2.base[i]) { - return false; - } - if(i == 0) { - break; - } - } - return false; - } - - bool operator< (const BigInteger& int2) { - BigInteger int2Copy = int2; - if(*this == BigInteger(0)) { - negative = false; - } - if(int2 == BigInteger(0)) { - int2Copy.negative = false; - } - if(negative != int2Copy.negative) { - return ((negative) ? true : false); - } - else { - return (isLess(int2Copy) != negative); - } - } - - bool operator> (const BigInteger& int2) { - return !(*this < int2) && *this != int2; - } - - bool operator<= (const BigInteger& int2) { - return !(*this > int2); - } - - bool operator>= (const BigInteger& int2) { - return !(*this < int2); - } - BigInteger& operator++() { *this = *this + BigInteger(1); if(*this >= BigInteger(0)) { @@ -501,23 +260,53 @@ class BigInteger { return ans; } - friend std::ostringstream& operator<<(std::ostringstream& os, const BigInteger& integer); + void normalizeZero() { + if(this != nullptr && *this == BigInteger(0)) { + negative = false; + } + } + friend std::ostringstream& operator<<(std::ostringstream& os, const BigInteger& integer); friend std::ostream& operator<<(std::ostream& os, const BigInteger& integer); - friend std::istringstream& operator>>(std::istringstream& is, BigInteger& integer); - friend bool operator== (const BigInteger& int1, const BigInteger& int2); + friend bool operator!= (const BigInteger& int1, const BigInteger& int2); + friend bool operator< (const BigInteger& int1, const BigInteger& int2); + friend bool isLess(const BigInteger& int1, const BigInteger& int2); + friend bool operator> (const BigInteger& int1, const BigInteger& int2); + friend bool operator<= (const BigInteger& int1, const BigInteger& int2); + friend bool operator>= (const BigInteger& int1, const BigInteger& int2); + friend BigInteger operator+ (const BigInteger& int1, const BigInteger& int2); + friend BigInteger operator- (const BigInteger& int1, const BigInteger& int2); + friend BigInteger operator* (const BigInteger& int1, const BigInteger& int2); + friend BigInteger operator/ (const BigInteger& int1, const BigInteger& int2); + friend BigInteger operator% (const BigInteger& int1, const BigInteger& int2); }; -bool checkDifferentSignsZeros(const std::vector& base1, const std::vector& base2) { - if(base1.size() == 1 && base1[0] == 0 && base2[0] == 0) { +bool isLess(const BigInteger& int1, const BigInteger& int2) { + if(int1.base.size() < int2.base.size()) { return true; } - else { + if(int1.base.size() > int2.base.size()) { return false; } + for(std::size_t i = int1.base.size() - 1; i >= 0; i--) { + if(int1.base[i] < int2.base[i]) { + return true; + } + if(int1.base[i] > int2.base[i]) { + return false; + } + if(i == 0) { + break; + } + } + return false; +} + +bool checkDifferentSignsZeros(const std::vector& base1, const std::vector& base2) { + return base1.size() == 1 && base1[0] == 0 && base2[0] == 0; } bool operator== (const BigInteger& int1, const BigInteger& int2) { @@ -529,7 +318,7 @@ bool operator== (const BigInteger& int1, const BigInteger& int2) { if(checkDifferentSignsZeros(base1, base2)) { return true; } - if(int1.getNegative() != int2.getNegative()) { + if(int1.negative != int2.negative) { return false; } for(std::size_t i = 0; i < base1.size(); i++) { @@ -540,6 +329,10 @@ bool operator== (const BigInteger& int1, const BigInteger& int2) { return true; } +bool operator!= (const BigInteger& int1, const BigInteger& int2) { + return !(int1 == int2); +} + std::ostringstream& operator<<(std::ostringstream& os, const BigInteger& integer) { os << ((integer.getNegative()) ? "-" : ""); std::vector base = integer.getBase(); @@ -553,13 +346,11 @@ std::ostringstream& operator<<(std::ostringstream& os, const BigInteger& integer } std::ostream& operator<<(std::ostream& os, const BigInteger& integer) { - os << ((integer.getNegative()) ? "-" : ""); - std::vector base = integer.getBase(); - for(std::size_t i = base.size() - 1; i >= 0; i--) { - os << base[i]; - if(i == 0) { - break; - } + os << ((integer.negative) ? "-" : ""); + std::vector base = integer.base; + std::cerr << base.size() << '\n'; + for(std::size_t i = 0; i < base.size(); i++) { + os << base[base.size() - 1 - i]; } return os; } @@ -568,8 +359,241 @@ std::istringstream& operator>>(std::istringstream& is, BigInteger& integer) { integer.base.clear(); std::string s; is >> s; - for(int i = s.size() - 1; i >= 0; i--) { - integer.base.push_back(s[i] - '0'); + for(std::size_t i = 0; i < s.size(); i++) { + integer.base.push_back(s[s.size() - 1 - i] - '0'); } return is; +} + +bool operator< (const BigInteger& int1, const BigInteger& int2) { + if(int1.negative != int2.negative) { + return ((int1.negative) ? true : false); + } + else { + return (isLess(int1, int2) != int1.negative); + } +} + +bool operator> (const BigInteger& int1, const BigInteger& int2) { + return !(int1 < int2) && int1 != int2; +} + +bool operator<= (const BigInteger& int1, const BigInteger& int2) { + return !(int1 > int2); +} + +bool operator>= (const BigInteger& int1, const BigInteger& int2) { + return !(int1 < int2); +} + +BigInteger operator+ (const BigInteger& int1, const BigInteger& int2) { + int next = 0; + BigInteger answer; + BigInteger a = int1; + BigInteger b = int2; + if(a.negative == false && b.negative == false) { + answer.negative = false; + } + else if(a.negative && !b.negative) { + a.negative = false; + answer = b - a; + return answer; + } + else if(!a.negative && b.negative) { + b.negative = false; + answer = a - b; + return answer; + } + else { + answer.negative = true; + } + if(a < b) { + std::swap(a, b); + } + for(std::size_t i = 0; i < a.base.size(); i++) { + if(i < b.base.size()) { + int num = a.base[i] + b.base[i] + next; + answer.base.push_back(num % 10); + next = (num / 10) % 10; + } + else { + answer.base.push_back(a.base[i] + next); + next = 0; + } + } + if(next != 0) { + answer.base.push_back(next); + } + answer.normalizeZero(); + return answer; +} + +BigInteger operator- (const BigInteger& int1, const BigInteger& int2) { + BigInteger answer; + BigInteger a = int1; + BigInteger b = int2; + if(a.negative == false && b.negative == false) { + answer.negative = false; + } + else if(a.negative && !b.negative) { + a.negative = false; + answer = a + b; + answer.negative = true; + return answer; + } + else if(!a.negative && b.negative) { + b.negative = false; + answer = a + b; + answer.negative = false; + return answer; + } + else { + std::swap(a, b); + answer.negative = false; + } + int inverse = 0; + if(a < b) { + std::swap(a, b); + inverse = 1; + } + int add = 0; + for(std::size_t i = 0; i < a.base.size(); i++) { + if(i < b.base.size()) { + if(a.base[i] - add >= b.base[i]) { + answer.base.push_back(a.base[i] - add - b.base[i]); + } + else { + answer.base.push_back(a.base[i] - add - b.base[i] + 10); + add = 1; + } + } + else { + if(a.base[i] >= add) { + answer.base.push_back(a.base[i] - add); + add = 0; + } + else { + answer.base.push_back(10 - add); + add = 1; + } + } + } + while(answer.base.size() && answer.base.back() == 0) { + answer.base.pop_back(); + } + if(answer.base.size() == 0) { + answer.base.push_back(0); + } + answer.negative ^= inverse; + answer.normalizeZero(); + return answer; +} + +BigInteger operator* (const BigInteger& int1, const BigInteger& int2) { + BigInteger a = int1; + BigInteger b = int2; + BigInteger answer; + Multiplicator multiplicator; + multiplicator.multiply(a.base, b.base, answer.base); + if(a.negative ^ b.negative) { + answer.negative = true; + } + else { + answer.negative = false; + } + for(std::size_t i = 0; i < answer.base.size() - 1; i++) { + if(i < answer.base.size() - 1) { + answer.base[i + 1] += answer.base[i] / 10; + answer.base[i] %= 10; + } + } + while(answer.base.back() != 0) { + int cnt = answer.base.back(); + answer.base[answer.base.size() - 1] %= 10; + answer.base.push_back(cnt / 10); + + } + while(answer.base.size() && answer.base.back() == 0) { + answer.base.pop_back(); + } + if(answer.base.size() == 0) { + answer.base.push_back(0); + } + answer.normalizeZero(); + return answer; +} + +BigInteger operator/ (const BigInteger& int1, const BigInteger& int2) { + BigInteger a = int1; + BigInteger b = int2; + BigInteger answer; + if(a.negative ^ b.negative) { + answer.negative = true; + } + else { + answer.negative = false; + } + a.negative = false; + b.negative = false; + int pos = a.base.size() - 1; + BigInteger cur = 0; + while(pos >= 0) { + std::cerr << cur << '\n'; + cur = cur * BigInteger(10) + BigInteger(a.base[pos]); + + pos--; + if(cur >= b) { + int num; + for(int i = 0; i < 10; i++) { + if((b * BigInteger(i)) > cur) { + num = i - 1; + break; + } + } + BigInteger bigNum = num; + cur = cur - (b * bigNum); + answer.base.push_back(num); + } + else { + answer.base.push_back(0); + } + } + reverse(answer.base.begin(), answer.base.end()); + while(answer.base.size() && answer.base.back() == 0) { + answer.base.pop_back(); + } + if(answer.base.size() == 0) { + answer.base.push_back(0); + } + answer.normalizeZero(); + return answer; +} + +BigInteger operator% (const BigInteger& int1, const BigInteger& int2) { + BigInteger a = int1; + BigInteger b = int2; + BigInteger answer = a; + bool negative = a.negative; + b.negative = false; + int pos = a.base.size() - 1; + BigInteger cur = 0; + while(pos >= 0) { + cur = cur * BigInteger(10) + BigInteger(a.base[pos]); + pos--; + if(cur >= b) { + int num; + for(int i = 0; i < 10; i++) { + if(b * BigInteger(i) > cur) { + num = i - 1; + break; + } + } + BigInteger bigNum = num; + cur = cur - (b * bigNum); + answer = cur; + } + } + answer.negative = negative; + answer.normalizeZero(); + return answer; } \ No newline at end of file