From 5082489e352ce4904da4d2f652760b8781cae561 Mon Sep 17 00:00:00 2001 From: fcostaoliveira Date: Fri, 3 Jul 2026 14:15:29 +0100 Subject: [PATCH] EXP-063: test the mode-independent mantissa bound before the rounds_to_nearest probe --- include/fast_float/parse_number.h | 29 +++++++++++++++++------------ 1 file changed, 17 insertions(+), 12 deletions(-) diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index 7d338f3..117ec69 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -198,7 +198,14 @@ clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative, // We proceed optimistically, assuming that detail::rounds_to_nearest() // returns true. if (binary_format::min_exponent_fast_path() <= exponent && - exponent <= binary_format::max_exponent_fast_path()) { + exponent <= binary_format::max_exponent_fast_path() && + mantissa <= binary_format::max_mantissa_fast_path()) { + // The mantissa bound above is a necessary condition for BOTH branches + // below: the rounding-mode-dependent branch checks the tighter + // max_mantissa_fast_path(exponent) <= max_mantissa_fast_path(). Testing + // it before detail::rounds_to_nearest() spares long-mantissa inputs + // (which can never take the fast path) the volatile-float probe. + // // Unfortunately, the conventional Clinger's fast path is only possible // when the system rounds to the nearest float. // @@ -209,18 +216,16 @@ clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative, if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) { // We have that fegetround() == FE_TONEAREST. // Next is Clinger's fast path. - if (mantissa <= binary_format::max_mantissa_fast_path()) { - value = T(mantissa); - if (exponent < 0) { - value = value / binary_format::exact_power_of_ten(-exponent); - } else { - value = value * binary_format::exact_power_of_ten(exponent); - } - if (is_negative) { - value = -value; - } - return true; + value = T(mantissa); + if (exponent < 0) { + value = value / binary_format::exact_power_of_ten(-exponent); + } else { + value = value * binary_format::exact_power_of_ten(exponent); } + if (is_negative) { + value = -value; + } + return true; } else { // We do not have that fegetround() == FE_TONEAREST. // Next is a modified Clinger's fast path, inspired by Jakub JelĂ­nek's