abacus: bignum: add is_canonicalized predicate

Useful when debugging.
This commit is contained in:
Bruno BELANYI 2021-08-20 16:51:00 +02:00
parent 12c8b6b114
commit 2cff603a48
2 changed files with 26 additions and 0 deletions

View file

@ -2,6 +2,7 @@
#include <algorithm>
#include <cassert>
#include <cmath>
namespace abacus::bignum {
@ -22,6 +23,8 @@ BigNum::BigNum(std::int64_t number) {
digits_.push_back(abs % 10);
abs /= 10;
} while (abs);
assert(is_canonicalized());
}
void BigNum::canonicalize() {
@ -32,6 +35,28 @@ void BigNum::canonicalize() {
if (digits_.size() == 0) {
sign_ = 0;
}
assert(is_canonicalized());
}
bool BigNum::is_canonicalized() const {
if (digits_.size() == 0) {
return sign_ == 0;
}
auto const leading_zeros = std::find_if(digits_.rbegin(), digits_.rend(),
[](auto v) { return v != 0; });
if (leading_zeros != digits_.rbegin()) {
return false;
}
auto const overflow = std::find_if(digits_.begin(), digits_.end(),
[](auto v) { return v >= 10; });
if (overflow != digits_.end()) {
return false;
}
return true;
}
} // namespace abacus::bignum

View file

@ -12,6 +12,7 @@ public:
private:
void canonicalize();
bool is_canonicalized() const;
std::vector<std::uint8_t> digits_{};
int sign_ = 0;