Add constexpr to more Number functions, and STAmount internals

- Check that min mantissa value for Number and STAmount is a power of
  10, and compute the max in terms of the min.
This commit is contained in:
Ed Hennis
2025-11-03 00:35:03 -05:00
parent f2b13dd69c
commit 72881a577d
3 changed files with 28 additions and 15 deletions

View File

@@ -32,6 +32,15 @@ class Number;
std::string
to_string(Number const& amount);
template <typename T>
constexpr bool
isPowerOfTen(T value)
{
while (value >= 10 && value % 10 == 0)
value /= 10;
return value == 1;
}
class Number
{
using rep = std::int64_t;
@@ -41,7 +50,9 @@ class Number
public:
// The range for the mantissa when normalized
constexpr static std::int64_t minMantissa = 1'000'000'000'000'000LL;
constexpr static std::int64_t maxMantissa = 9'999'999'999'999'999LL;
static_assert(isPowerOfTen(minMantissa));
constexpr static std::int64_t maxMantissa = minMantissa * 10 - 1;
static_assert(maxMantissa == 9'999'999'999'999'999LL);
// The range for the exponent when normalized
constexpr static int minExponent = -32768;
@@ -54,8 +65,8 @@ public:
explicit constexpr Number() = default;
Number(rep mantissa);
explicit Number(rep mantissa, int exponent);
constexpr Number(rep mantissa);
explicit constexpr Number(rep mantissa, int exponent);
explicit constexpr Number(rep mantissa, int exponent, unchecked) noexcept;
static Number const zero;
@@ -205,7 +216,7 @@ public:
private:
static thread_local rounding_mode mode_;
void
constexpr void
normalize();
constexpr bool
isnormal() const noexcept;
@@ -218,13 +229,13 @@ inline constexpr Number::Number(rep mantissa, int exponent, unchecked) noexcept
{
}
inline Number::Number(rep mantissa, int exponent)
inline constexpr Number::Number(rep mantissa, int exponent)
: mantissa_{mantissa}, exponent_{exponent}
{
normalize();
}
inline Number::Number(rep mantissa) : Number{mantissa, 0}
inline constexpr Number::Number(rep mantissa) : Number{mantissa, 0}
{
}

View File

@@ -66,16 +66,18 @@ public:
static int const cMaxOffset = 80;
// Maximum native value supported by the code
static std::uint64_t const cMinValue = 1'000'000'000'000'000ull;
static std::uint64_t const cMaxValue = 9'999'999'999'999'999ull;
static std::uint64_t const cMaxNative = 9'000'000'000'000'000'000ull;
constexpr static std::uint64_t cMinValue = 1'000'000'000'000'000ull;
static_assert(isPowerOfTen(cMinValue));
constexpr static std::uint64_t cMaxValue = cMinValue * 10 - 1;
static_assert(cMaxValue == 9'999'999'999'999'999ull);
constexpr static std::uint64_t cMaxNative = 9'000'000'000'000'000'000ull;
// Max native value on network.
static std::uint64_t const cMaxNativeN = 100'000'000'000'000'000ull;
static std::uint64_t const cIssuedCurrency = 0x8'000'000'000'000'000ull;
static std::uint64_t const cPositive = 0x4'000'000'000'000'000ull;
static std::uint64_t const cMPToken = 0x2'000'000'000'000'000ull;
static std::uint64_t const cValueMask = ~(cPositive | cMPToken);
constexpr static std::uint64_t cMaxNativeN = 100'000'000'000'000'000ull;
constexpr static std::uint64_t cIssuedCurrency = 0x8'000'000'000'000'000ull;
constexpr static std::uint64_t cPositive = 0x4'000'000'000'000'000ull;
constexpr static std::uint64_t cMPToken = 0x2'000'000'000'000'000ull;
constexpr static std::uint64_t cValueMask = ~(cPositive | cMPToken);
static std::uint64_t const uRateOne;

View File

@@ -243,7 +243,7 @@ Number::Guard::doRound(rep& drops)
constexpr Number one{1000000000000000, -15, Number::unchecked{}};
void
constexpr void
Number::normalize()
{
if (mantissa_ == 0)