|
|
@@ -21,7 +21,7 @@ namespace detail {
|
|
|
data_type add(data_type rhs, data_type const & lhs);
|
|
|
data_type subtract_nounderflow(data_type rhs, data_type const & lhs);
|
|
|
data_type multiply(data_type const & rhs, data_type const & lhs);
|
|
|
- data_type divide(data_type remainder, data_type const & divisor);
|
|
|
+ std::pair<data_type, data_type> divide(data_type remainder, data_type const & divisor);
|
|
|
}
|
|
|
|
|
|
static void swap(biginteger & rhs, biginteger && lhs) {
|
|
|
@@ -144,7 +144,7 @@ biginteger math::operator*(biginteger const & rhs, biginteger const & lhs) {
|
|
|
}
|
|
|
|
|
|
biginteger math::operator/(biginteger const & rhs, biginteger const & lhs) {
|
|
|
- if (lhs == biginteger::ZERO) { throw 0; }
|
|
|
+ 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}};
|
|
|
@@ -269,7 +269,7 @@ namespace detail {
|
|
|
data_type divide(data_type remainder, data_type const & divisor) {
|
|
|
data_type accum{0};
|
|
|
auto const dig = digits(divisor);
|
|
|
- while (detail::compare(remainder, divisor) >= 0) {
|
|
|
+ do {
|
|
|
auto const diff = digits(remainder) - dig - 1;
|
|
|
auto const shift = diff / biginteger::SEG_DIGITS;
|
|
|
auto const ipow = diff - (shift * biginteger::SEG_DIGITS);
|
|
|
@@ -279,7 +279,7 @@ namespace detail {
|
|
|
subtract_from(remainder, value);
|
|
|
add_into(accum, step);
|
|
|
} while (detail::compare(remainder, value) >= 0);
|
|
|
- }
|
|
|
+ } while (detail::compare(remainder, divisor) >= 0);
|
|
|
return accum;
|
|
|
}
|
|
|
}
|
|
|
@@ -307,9 +307,7 @@ bool math::operator>=(biginteger const & rhs, biginteger const & lhs) {
|
|
|
}
|
|
|
|
|
|
bool math::operator> (biginteger const & rhs, biginteger const & lhs) {
|
|
|
- if (rhs.is_negative != lhs.is_negative) { return lhs.is_negative; }
|
|
|
- else if (rhs.is_negative) { return detail::compare(rhs.data, lhs.data) < 0; }
|
|
|
- else { return detail::compare(rhs.data, lhs.data) > 0; }
|
|
|
+ return lhs < rhs;
|
|
|
}
|
|
|
|
|
|
biginteger const biginteger::ZERO{0}, biginteger::ONE{1}, biginteger::NEGATIVE_ONE{-1};
|