mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-10-31 11:26:28 +08:00
Skip the range check in compute_float after Clinger's range test under clang
If the exponent passed that test, the mantissa failed it, so it is not zero and the exponent is within range. GCC carries this into compute_float by itself. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
0900eedf2f
commit
ef5797fa94
@ -98,7 +98,9 @@ compute_error(int64_t q, uint64_t w) noexcept {
|
||||
// packed. However, in some very rare cases, the computation will fail. In such
|
||||
// cases, we return an adjusted_mantissa with a negative power of 2: the caller
|
||||
// should recompute in such cases.
|
||||
template <typename binary>
|
||||
// known_in_range: the caller knows that q is within the range of powers of
|
||||
// ten, so only w == 0 is checked.
|
||||
template <typename binary, bool known_in_range = false>
|
||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||
compute_float(int64_t q, uint64_t w) noexcept {
|
||||
adjusted_mantissa answer;
|
||||
@ -107,7 +109,7 @@ compute_float(int64_t q, uint64_t w) noexcept {
|
||||
bool const q_out_of_range = uint64_t(q - binary::smallest_power_of_ten()) >
|
||||
uint64_t(binary::largest_power_of_ten() -
|
||||
binary::smallest_power_of_ten());
|
||||
if ((w == 0) || q_out_of_range) {
|
||||
if ((w == 0) || (!known_in_range && q_out_of_range)) {
|
||||
bool const underflow = (w == 0) | (q < binary::smallest_power_of_ten());
|
||||
answer.power2 = int32_t(!underflow) * binary::infinite_power();
|
||||
answer.mantissa = 0;
|
||||
|
||||
@ -445,8 +445,20 @@ from_chars_float_advanced(UC const *first, UC const *last, T &value,
|
||||
return answer;
|
||||
}
|
||||
|
||||
#ifdef __clang__
|
||||
// If the exponent passed Clinger's range test, it is well within range. GCC
|
||||
// carries this into compute_float by itself; clang needs the instantiation
|
||||
// without the range check. The mantissa can still be zero when the rounding
|
||||
// mode is not to nearest.
|
||||
adjusted_mantissa am =
|
||||
(binary_format<T>::min_exponent_fast_path() <= pns.exponent &&
|
||||
pns.exponent <= binary_format<T>::max_exponent_fast_path())
|
||||
? compute_float<binary_format<T>, true>(pns.exponent, pns.mantissa)
|
||||
: compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
|
||||
#else
|
||||
adjusted_mantissa am =
|
||||
compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
|
||||
#endif
|
||||
// Slow path B (rare): Eisel-Lemire could not resolve; digit_comp needs the
|
||||
// integer/fraction spans. Route to the cold helper (clinger there is a
|
||||
// dead-effect since it already failed here; the cold re-parse + digit_comp
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user