mirror of
https://github.com/XRPLF/rippled.git
synced 2026-04-29 15:37:57 +00:00
refactor
This commit is contained in:
@@ -527,32 +527,11 @@ STAmount::fromNumber(A const& a, Number const& number)
|
||||
|
||||
auto const [mantissa, exponent] = working.normalizeToRange(cMinValue, cMaxValue);
|
||||
|
||||
// Special case: normalizeToRange returns mantissa=0 with Number's default
|
||||
// exponent (std::numeric_limits<int>::lowest()), but STAmount expects zero
|
||||
// IOUs to have the canonical zero offset. Handle this explicitly.
|
||||
if (mantissa == 0)
|
||||
{
|
||||
return STAmount{asset, 0, cZeroOffset, false, unchecked{}};
|
||||
}
|
||||
|
||||
// Handle underflow: if exponent is below minimum or mantissa is too small,
|
||||
// the value underflows to zero.
|
||||
if ((exponent < cMinOffset) || (mantissa < cMinValue))
|
||||
{
|
||||
return STAmount{asset, 0, cZeroOffset, false, unchecked{}};
|
||||
}
|
||||
|
||||
// Handle overflow: if exponent exceeds maximum, throw.
|
||||
if (exponent > cMaxOffset)
|
||||
Throw<std::runtime_error>("value overflow");
|
||||
|
||||
// normalizeToRange already produced canonical mantissa/exponent in the range
|
||||
// [cMinValue, cMaxValue], so bypass canonicalize() to avoid redundant work.
|
||||
XRPL_ASSERT(
|
||||
mantissa >= cMinValue && mantissa <= cMaxValue, "xrpl::STAmount::fromNumber : mantissa in canonical range");
|
||||
XRPL_ASSERT(
|
||||
exponent >= cMinOffset && exponent <= cMaxOffset, "xrpl::STAmount::fromNumber : exponent in canonical range");
|
||||
return STAmount{asset, static_cast<std::uint64_t>(mantissa), exponent, negative, unchecked{}};
|
||||
// normalizeToRange produces values in canonical mantissa range [cMinValue, cMaxValue],
|
||||
// but may produce out-of-range exponents for overflow/underflow cases.
|
||||
// Use the regular constructor - canonicalize() will detect already-normalized mantissa
|
||||
// and skip redundant scaling loops, while still handling overflow/underflow.
|
||||
return STAmount{asset, static_cast<std::uint64_t>(mantissa), exponent, negative};
|
||||
}
|
||||
|
||||
inline void
|
||||
|
||||
@@ -871,21 +871,30 @@ STAmount::canonicalize()
|
||||
return;
|
||||
}
|
||||
|
||||
while ((mValue < cMinValue) && (mOffset > cMinOffset))
|
||||
// Fast path: if mantissa is already in canonical range, skip scaling loops.
|
||||
// This handles values from normalizeToRange that only need overflow/underflow checks.
|
||||
bool const mantissaCanonical = (mValue >= cMinValue) && (mValue <= cMaxValue);
|
||||
|
||||
if (!mantissaCanonical)
|
||||
{
|
||||
mValue *= 10;
|
||||
--mOffset;
|
||||
}
|
||||
|
||||
while (mValue > cMaxValue)
|
||||
{
|
||||
if (mOffset >= cMaxOffset)
|
||||
Throw<std::runtime_error>("value overflow");
|
||||
|
||||
mValue /= 10;
|
||||
++mOffset;
|
||||
// Mantissa needs normalization
|
||||
while ((mValue < cMinValue) && (mOffset > cMinOffset))
|
||||
{
|
||||
mValue *= 10;
|
||||
--mOffset;
|
||||
}
|
||||
|
||||
while (mValue > cMaxValue)
|
||||
{
|
||||
if (mOffset >= cMaxOffset)
|
||||
Throw<std::runtime_error>("value overflow");
|
||||
|
||||
mValue /= 10;
|
||||
++mOffset;
|
||||
}
|
||||
}
|
||||
|
||||
// Check for underflow (applies whether we scaled or not)
|
||||
if ((mOffset < cMinOffset) || (mValue < cMinValue))
|
||||
{
|
||||
mValue = 0;
|
||||
@@ -894,6 +903,7 @@ STAmount::canonicalize()
|
||||
return;
|
||||
}
|
||||
|
||||
// Check for overflow (applies whether we scaled or not)
|
||||
if (mOffset > cMaxOffset)
|
||||
Throw<std::runtime_error>("value overflow");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user