|
|
@@ -24,10 +24,6 @@ namespace detail {
|
|
|
std::pair<data_type, data_type> divide(data_type remainder, data_type const & divisor);
|
|
|
}
|
|
|
|
|
|
-static void swap(biginteger & rhs, biginteger && lhs) {
|
|
|
- swap(rhs, lhs);
|
|
|
-}
|
|
|
-
|
|
|
biginteger::biginteger()
|
|
|
: biginteger(false, 0) {}
|
|
|
|
|
|
@@ -134,7 +130,17 @@ biginteger & math::operator*=(biginteger & rhs, biginteger const & lhs) {
|
|
|
}
|
|
|
|
|
|
biginteger & math::operator/=(biginteger & rhs, biginteger const & lhs) {
|
|
|
- swap(rhs, rhs / lhs);
|
|
|
+ rhs.is_negative ^= lhs.is_negative;
|
|
|
+ if (lhs == biginteger::ZERO) { throw std::domain_error("cannot divide by 0"); }
|
|
|
+ else if (rhs == biginteger::ZERO) { rhs = biginteger::ZERO; }
|
|
|
+ else if (detail::compare(lhs.data, {1}) != 0) {
|
|
|
+ auto cmp = detail::compare(rhs.data, lhs.data);
|
|
|
+ if (cmp < 0) { rhs = biginteger::ZERO; }
|
|
|
+ else if (cmp == 0) { rhs.data = {1}; }
|
|
|
+ else {
|
|
|
+ rhs.data = detail::divide(rhs.data, lhs.data).first;
|
|
|
+ }
|
|
|
+ }
|
|
|
return rhs;
|
|
|
}
|
|
|
|
|
|
@@ -154,28 +160,17 @@ biginteger math::operator*(biginteger rhs, biginteger const & lhs) {
|
|
|
return rhs *= lhs;
|
|
|
}
|
|
|
|
|
|
-biginteger math::operator/(biginteger const & rhs, biginteger const & lhs) {
|
|
|
- if (lhs == biginteger::ZERO) { throw std::domain_error("cannot divide by 0"); }
|
|
|
- else if (rhs == biginteger::ZERO) { return biginteger::ZERO; }
|
|
|
- else if (detail::compare(lhs.data, {1}) == 0) {
|
|
|
- return {rhs.is_negative != lhs.is_negative, biginteger::data_type{rhs.data}};
|
|
|
- } else {
|
|
|
- auto cmp = detail::compare(rhs.data, lhs.data);
|
|
|
- bool is_neg = rhs.is_negative != lhs.is_negative;
|
|
|
- if (cmp < 0) { return biginteger::ZERO; }
|
|
|
- else if (cmp == 0) { return {is_neg, {1}}; }
|
|
|
- else { return {is_neg, detail::divide(rhs.data, lhs.data).first}; }
|
|
|
- }
|
|
|
+biginteger math::operator/(biginteger rhs, biginteger const & lhs) {
|
|
|
+ return rhs /= lhs;
|
|
|
}
|
|
|
|
|
|
-biginteger math::operator%(biginteger const & rhs, biginteger const & lhs) {
|
|
|
+biginteger math::operator%(biginteger rhs, biginteger const & lhs) {
|
|
|
if (lhs == biginteger::ZERO) { throw std::domain_error("cannot divide by 0"); }
|
|
|
else if (detail::compare(lhs.data, biginteger::ONE.data) == 0 ||
|
|
|
rhs == biginteger::ZERO) { return biginteger::ZERO; }
|
|
|
else {
|
|
|
auto cmp = detail::compare(rhs.data, lhs.data);
|
|
|
- if (cmp < 0) { return rhs; }
|
|
|
- else if (cmp == 0) { return biginteger::ZERO; }
|
|
|
+ if (cmp == 0) { return biginteger::ZERO; }
|
|
|
else {
|
|
|
auto data = detail::divide(rhs.data, lhs.data).second;
|
|
|
if (detail::compare(data, {0}) == 0) { return biginteger::ZERO; }
|