|
|
@@ -30,15 +30,9 @@ namespace math { namespace detail {
|
|
|
}
|
|
|
#undef IMPL_COMPARE
|
|
|
|
|
|
- void add(data_type & rhs, data_type const & lhs, size_t offset) {
|
|
|
- rhs.resize(std::max(rhs.size(), lhs.size()+offset)+1);
|
|
|
- auto const lbnd = lhs.size(), ubnd = rhs.size() - 1;
|
|
|
- // Add
|
|
|
- for (size_t i = 0; i < lbnd; ++i) {
|
|
|
- rhs[i+offset] += lhs[i];
|
|
|
- }
|
|
|
- // Carry
|
|
|
- for (size_t i = 0; i < ubnd; ++i) {
|
|
|
+ void carry(data_type & rhs, size_t start) {
|
|
|
+ auto const ubnd = rhs.size() - 1;
|
|
|
+ for (size_t i = start; i < ubnd; ++i) {
|
|
|
if (rhs[i] > MAX_SEG) {
|
|
|
rhs[i] -= OVER_SEG;
|
|
|
rhs[i+1] += 1;
|
|
|
@@ -47,6 +41,21 @@ namespace math { namespace detail {
|
|
|
if (rhs[ubnd] == 0) { rhs.pop_back(); }
|
|
|
}
|
|
|
|
|
|
+ void add(data_type & rhs, data_type const & lhs, size_t offset) {
|
|
|
+ rhs.resize(std::max(rhs.size(), lhs.size()+offset)+1);
|
|
|
+ auto const lbnd = lhs.size();
|
|
|
+ for (size_t i = 0; i < lbnd; ++i) {
|
|
|
+ rhs[i+offset] += lhs[i];
|
|
|
+ }
|
|
|
+ carry(rhs, offset);
|
|
|
+ }
|
|
|
+
|
|
|
+ void add(data_type & rhs, int32_t lhs, size_t offset) {
|
|
|
+ rhs.resize(std::max(rhs.size(), offset)+1);
|
|
|
+ rhs[offset] += lhs;
|
|
|
+ carry(rhs, offset);
|
|
|
+ }
|
|
|
+
|
|
|
void subtract_nounderflow(data_type & rhs, data_type const & lhs, size_t offset) {
|
|
|
size_t const rbnd = rhs.size(), lbnd = lhs.size();
|
|
|
// Subtract
|
|
|
@@ -121,12 +130,11 @@ namespace math { namespace detail {
|
|
|
auto const diff = std::max(1UL, digits(remainder) - dig) - 1;
|
|
|
auto const shift = diff / SEG_DIGITS;
|
|
|
auto const ipow = diff - (shift * SEG_DIGITS);
|
|
|
- data_type step{shift10({1}, powers[ipow], 0)};
|
|
|
data_type value{shift10(divisor, powers[ipow], 0)};
|
|
|
do {
|
|
|
subtract_nounderflow(remainder, value, shift);
|
|
|
- add(accum, step, shift);
|
|
|
- } while (compare(remainder, value) >= 0);
|
|
|
+ add(accum, powers[ipow], shift);
|
|
|
+ } while (compare(remainder, value) >= 0); // Up to 9 times
|
|
|
} while (compare(remainder, divisor) >= 0);
|
|
|
return accum;
|
|
|
}
|