added 16 byte/chars step to the parse_mantissa.

This commit is contained in:
HedgehogInTheCPP 2026-08-21 16:15:57 +03:00
parent 9e5fc2693c
commit 33bf1b3dbd
2 changed files with 46 additions and 10 deletions

View File

@ -217,6 +217,16 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 bool
is_truncated(span<UC const> 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 <typename UC>
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void
@ -228,6 +238,16 @@ parse_eight_digits(UC const *&p, limb &value, am_digits &counter,
count += 8;
}
template <typename UC>
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<uint32_t>(p));
p += 4;
counter += 4;
count += 4;
}
template <typename UC>
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<UC> &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<limb>(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<UC> &num) noexcept {
}
return digits;
} else {
add_native(result, limb(powers_of_ten_uint64[counter]), value);
add_native(result, static_cast<limb>(powers_of_ten_uint64[counter]),
value);
counter = 0;
value = 0;
}
@ -318,14 +352,16 @@ parse_mantissa(bigint &result, const parsed_number_string_t<UC> &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<limb>(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<limb>(powers_of_ten_uint64[counter]),
value);
counter = 0;
value = 0;
}
@ -333,7 +369,7 @@ parse_mantissa(bigint &result, const parsed_number_string_t<UC> &num) noexcept {
}
if (counter != 0) {
add_native(result, limb(powers_of_ten_uint64[counter]), value);
add_native(result, static_cast<limb>(powers_of_ten_uint64[counter]), value);
}
return digits;
}

View File

@ -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<T>::max_mantissa_fast_path()) {
value = T(mantissa);
value = static_cast<T>(mantissa);
if (exponent < 0) {
value = value / binary_format<T>::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<T>(-0.) :
#endif
T(0.);
static_cast<T>(0.);
return true;
}
#endif
value = T(mantissa) * binary_format<T>::exact_power_of_ten(exponent);
value = static_cast<T>(mantissa) * binary_format<T>::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<UC>::value,
"only char, wchar_t, char16_t and char32_t are supported");
parse_options_t<UC> const options(chars_format::general, UC('.'),
parse_options_t<UC> const options(chars_format::general, static_cast<UC>('.'),
static_cast<base_t>(base));
return from_chars_advanced(first, last, value, options);
}