|
|
@@ -79,12 +79,12 @@ void bigdecimal::set_scale(int32_t nscale) {
|
|
|
}
|
|
|
|
|
|
void bigdecimal::rescale(int32_t nscale) {
|
|
|
- int32_t const nsteps = add_scale(nscale);
|
|
|
- if (steps_ > nsteps) {
|
|
|
- data.erase(data.begin(), data.begin() + steps_ - nsteps);
|
|
|
+ auto const diff = steps_ - add_scale(nscale);
|
|
|
+ if (diff > 0) {
|
|
|
+ data.erase(data.begin(), data.begin() + diff);
|
|
|
if (data.empty()) { data.push_back(0); }
|
|
|
- } else if (steps_ < nsteps) {
|
|
|
- data.insert(data.begin(), size_t(nsteps-steps_), 0);
|
|
|
+ } else if (diff < 0) {
|
|
|
+ data.insert(data.begin(), size_t(-diff), 0);
|
|
|
}
|
|
|
auto const idx = -nscale % SEG_DIGITS;
|
|
|
if (scale() > nscale && nscale < 0 && idx) {
|
|
|
@@ -149,10 +149,21 @@ static bool all_zero(bigdecimal::data_type const & data, size_t from) {
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+static int compare(bigdecimal::data_type const & ldata, bigdecimal::data_type const & rdata, size_t offset) {
|
|
|
+ auto cmp = detail::compare(ldata, rdata, offset);
|
|
|
+ if (cmp == 0) { return !all_zero(ldata, offset); }
|
|
|
+ return cmp;
|
|
|
+}
|
|
|
+
|
|
|
+static int compare(bigdecimal::data_type const & ldata, int32_t lsteps, bigdecimal::data_type const & rdata, int32_t rsteps) {
|
|
|
+ return lsteps < rsteps ?
|
|
|
+ compare(rdata, ldata, size_t(rsteps - lsteps))
|
|
|
+ : compare(ldata, rdata, size_t(lsteps - rsteps));
|
|
|
+}
|
|
|
+
|
|
|
static bool is_one(bigdecimal::data_type const & data, int32_t scale) {
|
|
|
static bigdecimal::data_type ONE = {1};
|
|
|
- auto ms = mul_scale(scale);
|
|
|
- return scale >= 0 && detail::compare(data, ONE, ms) == 0 && all_zero(data, ms);
|
|
|
+ return compare(data, add_scale(scale), ONE, 0) == 0;
|
|
|
}
|
|
|
|
|
|
bigdecimal & math::operator*=(bigdecimal & rhs, bigdecimal const & lhs) {
|
|
|
@@ -223,7 +234,7 @@ bigdecimal math::operator/(bigdecimal rhs, bigdecimal const & 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
|
|
|
+ return lhs.is_negative == rhs.is_negative && compare(lhs.data, lhs.steps_, rhs.data, rhs.steps_) == 0;
|
|
|
}
|
|
|
|
|
|
bigdecimal const bigdecimal::ZERO{0}, bigdecimal::ONE{1}, bigdecimal::NEGATIVE_ONE{-1};
|