mirror of
https://github.com/XRPLF/rippled.git
synced 2026-06-07 10:47:05 +00:00
Revert "Rollback Number class changes; show the fix works without side effects"
This reverts commit 8743be8eae.
This commit is contained in:
@@ -51,37 +51,43 @@ namespace detail {
|
||||
* compile time. Doing it at runtime would be pretty wasteful and
|
||||
* inefficient.
|
||||
*/
|
||||
constexpr std::size_t kInt64Digits = 20;
|
||||
consteval std::array<std::uint64_t, kInt64Digits>
|
||||
constexpr std::size_t kUint64Digits = 20;
|
||||
constexpr std::size_t kUint128Digits = 39;
|
||||
|
||||
template <typename T, std::size_t Digits>
|
||||
consteval std::array<T, Digits>
|
||||
buildPowersOfTen()
|
||||
{
|
||||
std::array<std::uint64_t, kInt64Digits> result{};
|
||||
std::array<T, Digits> result{};
|
||||
|
||||
std::uint64_t power = 1;
|
||||
T power = 1;
|
||||
std::size_t exponent = 0;
|
||||
// end the loop early so it doesn't overflow;
|
||||
for (; exponent < result.size() - 1; ++exponent, power *= 10)
|
||||
{
|
||||
result[exponent] = power;
|
||||
if (power > std::numeric_limits<std::uint64_t>::max() / 10)
|
||||
if (power > std::numeric_limits<T>::max() / 10)
|
||||
throw std::logic_error("Power of 10 table is too big");
|
||||
}
|
||||
result[exponent] = power;
|
||||
if (power < std::numeric_limits<std::uint64_t>::max() / 10)
|
||||
throw std::logic_error("Power of 10 table is not big enough for the uint64_t type");
|
||||
if (power < std::numeric_limits<T>::max() / 10)
|
||||
throw std::logic_error("Power of 10 table is not big enough for the given type");
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
constexpr std::array<std::uint64_t, detail::kInt64Digits> kPowerOfTen = detail::buildPowersOfTen();
|
||||
template <typename T = std::uint64_t, std::size_t Digits = detail::kUint64Digits>
|
||||
constexpr std::array<T, Digits> kPowerOfTenImpl = detail::buildPowersOfTen<T, Digits>();
|
||||
|
||||
constexpr auto kPowerOfTen = kPowerOfTenImpl<std::uint64_t, detail::kUint64Digits>;
|
||||
|
||||
static_assert(kPowerOfTen[0] == 1);
|
||||
static_assert(kPowerOfTen[1] == 10);
|
||||
static_assert(kPowerOfTen[10] == 10'000'000'000);
|
||||
static_assert(
|
||||
isPowerOfTen(kPowerOfTen.back()) && *logTen(kPowerOfTen.back()) == detail::kInt64Digits - 1);
|
||||
isPowerOfTen(kPowerOfTen.back()) && *logTen(kPowerOfTen.back()) == detail::kUint64Digits - 1);
|
||||
|
||||
/** MantissaRange defines a range for the mantissa of a normalized Number.
|
||||
*
|
||||
@@ -141,7 +147,7 @@ struct MantissaRange final
|
||||
int const log{getExponent(scale)};
|
||||
rep const min{getMin(scale, log)};
|
||||
rep const max{(min * 10) - 1};
|
||||
CuspRoundingFix const cuspRoundingFixEnabled{isCuspFixEnabled(scale)};
|
||||
CuspRoundingFix const cuspRoundingFix{isCuspFixEnabled(scale)};
|
||||
|
||||
static MantissaRange const&
|
||||
getMantissaRange(MantissaScale scale);
|
||||
@@ -543,9 +549,15 @@ private:
|
||||
// changing the values inside the range.
|
||||
static thread_local std::reference_wrapper<MantissaRange const> kRange;
|
||||
|
||||
class Guard;
|
||||
|
||||
void
|
||||
normalize(MantissaRange const& range);
|
||||
|
||||
// Guard has the fields that we need, as well as MantissaRange, so if we have a guard, use that
|
||||
void
|
||||
normalize(Guard const& guard);
|
||||
|
||||
/** Normalize Number components to an arbitrary range.
|
||||
*
|
||||
* min/maxMantissa are parameters because this function is used by both
|
||||
@@ -560,7 +572,7 @@ private:
|
||||
int& exponent,
|
||||
internalrep const& minMantissa,
|
||||
internalrep const& maxMantissa,
|
||||
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled);
|
||||
MantissaRange::CuspRoundingFix cuspRoundingFix);
|
||||
|
||||
template <class T>
|
||||
friend void
|
||||
@@ -570,7 +582,7 @@ private:
|
||||
int& exponent,
|
||||
MantissaRange::rep const& minMantissa,
|
||||
MantissaRange::rep const& maxMantissa,
|
||||
MantissaRange::CuspRoundingFix cuspRoundingFixEnabled,
|
||||
MantissaRange::CuspRoundingFix cuspRoundingFix,
|
||||
bool dropped);
|
||||
|
||||
[[nodiscard]] bool
|
||||
@@ -588,8 +600,6 @@ private:
|
||||
// UB, and can vary across compilers.
|
||||
static internalrep
|
||||
externalToInternal(rep mantissa);
|
||||
|
||||
class Guard;
|
||||
};
|
||||
|
||||
constexpr Number::Number(bool negative, internalrep mantissa, int exponent, Unchecked) noexcept
|
||||
|
||||
Reference in New Issue
Block a user