docs: Cut the unverifiable clauses from normalizeToRange

The @note comparing this overload to the two-pass path stated where the two
diverge and called the first range "strictly wider". Both were wrong: they also
diverge below kMinExponent, and MantissaScale::Small is the IOU range exactly,
not wider. The comparison is not a contract a caller needs, so drop it rather
than reword it, and state only what the function returns.
This commit is contained in:
Pratik Mankawde
2026-09-23 18:22:35 +01:00
parent 2c2b747881
commit 09b9cf8d6a
2 changed files with 6 additions and 23 deletions

View File

@@ -618,16 +618,8 @@ public:
* @param mantissa Raw signed mantissa (sign is extracted internally).
* @param exponent Raw exponent.
* @return The normalized (mantissa, exponent) pair in the target range.
* A zero mantissa returns the canonical zero a default-constructed
* Number holds, {0, std::numeric_limits<int>::lowest()}. The sign
* of a zero is not preserved.
* @note Bit-identical to normalizing through a strictly wider range first
* for every exponent reachable through IOUAmount, which bounds its
* own exponent to [STAmount::kMinOffset, STAmount::kMaxOffset]. The
* two diverge only at exponent == kMinExponent: there the wider pass
* has no headroom left to scale a below-minimum mantissa up, so it
* collapses to zero, whereas this one scales down into the target
* range and keeps the value.
* A zero mantissa returns {0, std::numeric_limits<int>::lowest()};
* the sign of a zero is not preserved.
* @note Thread-safety: reads the thread-local rounding mode only; holds no
* shared state of its own. Safe to call concurrently.
*

View File

@@ -3235,10 +3235,7 @@ TEST(NumberTest, normalize_to_range_member_static_consistency)
}
}
// A zero mantissa short-circuits normalization: the canonical zero is copied
// out of a default-constructed Number, whose exponent is
// std::numeric_limits<int>::lowest(), and the exponent handed in is ignored.
// Pinned because the documented return value names that sentinel.
// A zero mantissa returns the zero sentinel, ignoring the exponent passed in.
TEST(NumberTest, normalize_to_range_zero_mantissa)
{
for (int const e : {Number::kMinExponent, -90, -1, 0, 1, 90, Number::kMaxExponent})
@@ -3249,17 +3246,11 @@ TEST(NumberTest, normalize_to_range_zero_mantissa)
}
}
// The one-pass and two-pass paths agree on every exponent IOUAmount can reach,
// but not at Number's exponent floor. There the two-pass path's first
// normalization has no headroom left to scale a below-minimum mantissa up, so
// it collapses to zero, while the single pass scales down into the IOU range
// and keeps the value. Pinned so that divergence stays deliberate. IOUAmount
// cannot reach this input, because STAmount bounds its exponent to
// [kMinOffset, kMaxOffset].
// At the exponent floor the two paths differ: the two-pass path zeroes, while
// the single pass scales down and keeps the value.
TEST(NumberTest, normalize_to_range_exponent_floor_diverges_from_two_pass)
{
// 10^17: two decades above the IOU minimum, yet still below the default
// Large330 minimum of 10^18 that the two-pass path normalizes to first.
// 10^17: above the IOU minimum, below the Large330 minimum of 10^18.
constexpr std::int64_t kBelowWideMin = kMin * 100;
auto const [oneM, oneE] = onePass(kBelowWideMin, Number::kMinExponent);