From 33bf1b3dbdcb0de3ddc59a77a8b69aca5898c24b Mon Sep 17 00:00:00 2001 From: HedgehogInTheCPP Date: Fri, 21 Aug 2026 16:15:57 +0300 Subject: [PATCH] added 16 byte/chars step to the parse_mantissa. --- include/fast_float/digit_comparison.h | 46 ++++++++++++++++++++++++--- include/fast_float/parse_number.h | 10 +++--- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index c29a83e..450fd1c 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -217,6 +217,16 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool is_truncated(span s) noexcept { return is_truncated(s.ptr, s.ptr + s.len()); } +#ifdef FASTFLOAT_64BIT_LIMB && FASTFLOAT_X86_SIMD >= 31 +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +parse_sixteen_digits(char const *&p, limb &value, am_digits &counter, + am_digits &count) noexcept { + value = parse_16_digits(p); + p += 16; + counter += 16; + count += 16; +} +#endif template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void @@ -228,6 +238,16 @@ parse_eight_digits(UC const *&p, limb &value, am_digits &counter, count += 8; } +template +fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void +parse_four_digits(UC const *&p, limb &value, am_digits &counter, + am_digits &count) noexcept { + value = value * 10000 + parse_4_digits(read_chars_to_unsigned(p)); + p += 4; + counter += 4; + count += 4; +} + template fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void parse_one_digit(UC const *&p, limb &value, am_digits &counter, @@ -275,16 +295,29 @@ parse_mantissa(bigint &result, const parsed_number_string_t &num) noexcept { skip_zeros(p, pend); // process all digits, in increments of step per loop while (p != pend) { +#ifdef FASTFLOAT_64BIT_LIMB &&FASTFLOAT_X86_SIMD >= 31 + if FASTFLOAT_CONSTEXPR17 (sizeof(UC) == 1) { + if (!is_constant_evaluated() && (std::distance(p, pend) >= 16) && + (step - counter >= 16) && (max_digits - digits >= 16)) { + parse_sixteen_digits(p, value, counter, digits); + } + } +#endif while ((std::distance(p, pend) >= 8) && (step - counter >= 8) && (max_digits - digits >= 8)) { parse_eight_digits(p, value, counter, digits); } + while ((std::distance(p, pend) >= 4) && (step - counter >= 4) && + (max_digits - digits >= 4)) { + parse_four_digits(p, value, counter, digits); + } while (counter < step && p != pend && digits < max_digits) { parse_one_digit(p, value, counter, digits); } if (digits == max_digits) { // add the temporary value, then check if we've truncated any digits - add_native(result, limb(powers_of_ten_uint64[counter]), value); + add_native(result, static_cast(powers_of_ten_uint64[counter]), + value); bool truncated = is_truncated(p, pend); if (num.fraction.ptr != nullptr) { truncated |= is_truncated(num.fraction); @@ -294,7 +327,8 @@ parse_mantissa(bigint &result, const parsed_number_string_t &num) noexcept { } return digits; } else { - add_native(result, limb(powers_of_ten_uint64[counter]), value); + add_native(result, static_cast(powers_of_ten_uint64[counter]), + value); counter = 0; value = 0; } @@ -318,14 +352,16 @@ parse_mantissa(bigint &result, const parsed_number_string_t &num) noexcept { } if (digits == max_digits) { // add the temporary value, then check if we've truncated any digits - add_native(result, limb(powers_of_ten_uint64[counter]), value); + add_native(result, static_cast(powers_of_ten_uint64[counter]), + value); bool truncated = is_truncated(p, pend); if (truncated) { round_up_bigint(result, digits); } return digits; } else { - add_native(result, limb(powers_of_ten_uint64[counter]), value); + add_native(result, static_cast(powers_of_ten_uint64[counter]), + value); counter = 0; value = 0; } @@ -333,7 +369,7 @@ parse_mantissa(bigint &result, const parsed_number_string_t &num) noexcept { } if (counter != 0) { - add_native(result, limb(powers_of_ten_uint64[counter]), value); + add_native(result, static_cast(powers_of_ten_uint64[counter]), value); } return digits; } diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index fcafc4a..bc7f6ff 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -226,7 +226,7 @@ clinger_fast_path_impl(am_mant_t const mantissa, am_pow_t const exponent, // We have that fegetround() == FE_TONEAREST. // Next is Clinger's fast path. if (mantissa <= binary_format::max_mantissa_fast_path()) { - value = T(mantissa); + value = static_cast(mantissa); if (exponent < 0) { value = value / binary_format::exact_power_of_ten(-exponent); } else { @@ -250,13 +250,13 @@ clinger_fast_path_impl(am_mant_t const mantissa, am_pow_t const exponent, if (mantissa == 0) { value = #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN - is_negative ? T(-0.) : + is_negative ? static_cast(-0.) : #endif - T(0.); + static_cast(0.); return true; } #endif - value = T(mantissa) * binary_format::exact_power_of_ten(exponent); + value = static_cast(mantissa) * binary_format::exact_power_of_ten(exponent); #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN if (is_negative) { value = -value; @@ -470,7 +470,7 @@ from_chars(UC const *first, UC const *last, T &value, int const base) noexcept { static_assert(is_supported_char_type::value, "only char, wchar_t, char16_t and char32_t are supported"); - parse_options_t const options(chars_format::general, UC('.'), + parse_options_t const options(chars_format::general, static_cast('.'), static_cast(base)); return from_chars_advanced(first, last, value, options); }