|
|
@@ -127,7 +127,7 @@ bigdecimal & math::operator-=(bigdecimal & rhs, bigdecimal const & lhs) {
|
|
|
rhs.rescale(new_scale);
|
|
|
size_t const offset = size_t(rhs.get_impl_scale() - lhs.get_impl_scale());
|
|
|
if (lhs == bigdecimal::ZERO) { return rhs; }
|
|
|
- else if (rhs == bigdecimal::ZERO) { rhs = -lhs; }
|
|
|
+ else if (rhs == bigdecimal::ZERO) { rhs.set_value(-lhs); }
|
|
|
else if (rhs.is_negative != lhs.is_negative) {
|
|
|
detail::add(rhs.data, lhs.data, offset);
|
|
|
} else {
|
|
|
@@ -141,19 +141,38 @@ bigdecimal & math::operator*=(bigdecimal & rhs, bigdecimal const & lhs) {
|
|
|
size_t const offset = mul_scale(rhs.scale_) + mul_scale(lhs.scale_) - mul_scale(new_scale);
|
|
|
bool is_neg = rhs.is_negative != lhs.is_negative;
|
|
|
if (rhs == bigdecimal::ZERO || lhs == bigdecimal::ZERO) {
|
|
|
- rhs.set_value(bigdecimal::ZERO);
|
|
|
- rhs.rescale(new_scale);
|
|
|
+ rhs = bigdecimal::ZERO;
|
|
|
} else if (detail::compare(lhs.data, bigdecimal::ONE.data) == 0) {
|
|
|
rhs.is_negative = is_neg;
|
|
|
- rhs.rescale(new_scale);
|
|
|
} else if (detail::compare(rhs.data, bigdecimal::ONE.data) == 0) {
|
|
|
- rhs.data = lhs.data;
|
|
|
+ rhs = lhs;
|
|
|
rhs.is_negative = is_neg;
|
|
|
- rhs.rescale(new_scale);
|
|
|
} else {
|
|
|
detail::multiply(rhs.data, lhs.data, offset);
|
|
|
rhs.scale_ = new_scale; // TODO: more steps in certain cases
|
|
|
+ return rhs;
|
|
|
}
|
|
|
+ rhs.rescale(new_scale);
|
|
|
+ return rhs;
|
|
|
+}
|
|
|
+
|
|
|
+bigdecimal & math::operator/=(bigdecimal & rhs, bigdecimal const & lhs) {
|
|
|
+ int32_t const new_scale = rhs.scale_ - lhs.scale_;
|
|
|
+ rhs.is_negative ^= lhs.is_negative;
|
|
|
+ if (lhs == bigdecimal::ZERO) { throw std::domain_error("cannot divide by 0"); }
|
|
|
+ else if (rhs == bigdecimal::ZERO) {
|
|
|
+ rhs = bigdecimal::ZERO;
|
|
|
+ } else if (detail::compare(lhs.data, bigdecimal::ONE.data) != 0) {
|
|
|
+ auto cmp = detail::compare(rhs.data, lhs.data);
|
|
|
+ if (cmp < 0) { rhs = bigdecimal::ZERO; }
|
|
|
+ else if (cmp == 0) { rhs.data = {1}; }
|
|
|
+ else {
|
|
|
+ rhs.data = detail::divide(rhs.data, lhs.data);
|
|
|
+ rhs.scale_ = new_scale;
|
|
|
+ return rhs;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ rhs.rescale(new_scale);
|
|
|
return rhs;
|
|
|
}
|
|
|
|
|
|
@@ -169,6 +188,10 @@ bigdecimal math::operator*(bigdecimal rhs, bigdecimal const & lhs) {
|
|
|
return rhs *= lhs;
|
|
|
}
|
|
|
|
|
|
+bigdecimal math::operator/(bigdecimal rhs, bigdecimal const & lhs) {
|
|
|
+ return rhs /= lhs;
|
|
|
+}
|
|
|
+
|
|
|
bool math::operator==(bigdecimal const & lhs, bigdecimal const & rhs) {
|
|
|
return lhs.is_negative == rhs.is_negative && detail::compare(lhs.data, rhs.data) == 0; // TODO
|
|
|
}
|