Skip to content

Commit 5082489

Browse files
EXP-063: test the mode-independent mantissa bound before the rounds_to_nearest probe
1 parent f4f36e0 commit 5082489

1 file changed

Lines changed: 17 additions & 12 deletions

File tree

include/fast_float/parse_number.h

Lines changed: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -198,7 +198,14 @@ clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
198198
// We proceed optimistically, assuming that detail::rounds_to_nearest()
199199
// returns true.
200200
if (binary_format<T>::min_exponent_fast_path() <= exponent &&
201-
exponent <= binary_format<T>::max_exponent_fast_path()) {
201+
exponent <= binary_format<T>::max_exponent_fast_path() &&
202+
mantissa <= binary_format<T>::max_mantissa_fast_path()) {
203+
// The mantissa bound above is a necessary condition for BOTH branches
204+
// below: the rounding-mode-dependent branch checks the tighter
205+
// max_mantissa_fast_path(exponent) <= max_mantissa_fast_path(). Testing
206+
// it before detail::rounds_to_nearest() spares long-mantissa inputs
207+
// (which can never take the fast path) the volatile-float probe.
208+
//
202209
// Unfortunately, the conventional Clinger's fast path is only possible
203210
// when the system rounds to the nearest float.
204211
//
@@ -209,18 +216,16 @@ clinger_fast_path_impl(uint64_t mantissa, int64_t exponent, bool is_negative,
209216
if (!cpp20_and_in_constexpr() && detail::rounds_to_nearest()) {
210217
// We have that fegetround() == FE_TONEAREST.
211218
// Next is Clinger's fast path.
212-
if (mantissa <= binary_format<T>::max_mantissa_fast_path()) {
213-
value = T(mantissa);
214-
if (exponent < 0) {
215-
value = value / binary_format<T>::exact_power_of_ten(-exponent);
216-
} else {
217-
value = value * binary_format<T>::exact_power_of_ten(exponent);
218-
}
219-
if (is_negative) {
220-
value = -value;
221-
}
222-
return true;
219+
value = T(mantissa);
220+
if (exponent < 0) {
221+
value = value / binary_format<T>::exact_power_of_ten(-exponent);
222+
} else {
223+
value = value * binary_format<T>::exact_power_of_ten(exponent);
224+
}
225+
if (is_negative) {
226+
value = -value;
223227
}
228+
return true;
224229
} else {
225230
// We do not have that fegetround() == FE_TONEAREST.
226231
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's

0 commit comments

Comments
 (0)