From 2cff603a488468a7798e0af980951eb449d16438 Mon Sep 17 00:00:00 2001 From: Bruno BELANYI Date: Fri, 20 Aug 2021 16:51:00 +0200 Subject: [PATCH] abacus: bignum: add is_canonicalized predicate Useful when debugging. --- src/bignum/bignum.cc | 25 +++++++++++++++++++++++++ src/bignum/bignum.hh | 1 + 2 files changed, 26 insertions(+) diff --git a/src/bignum/bignum.cc b/src/bignum/bignum.cc index 6a1f62c..e47c9b8 100644 --- a/src/bignum/bignum.cc +++ b/src/bignum/bignum.cc @@ -2,6 +2,7 @@ #include +#include #include 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 diff --git a/src/bignum/bignum.hh b/src/bignum/bignum.hh index 54db82b..c814e75 100644 --- a/src/bignum/bignum.hh +++ b/src/bignum/bignum.hh @@ -12,6 +12,7 @@ public: private: void canonicalize(); + bool is_canonicalized() const; std::vector digits_{}; int sign_ = 0;