initialization cleanup and improve caches usage.

This commit is contained in:
IRainman 2025-12-29 16:17:44 +03:00
parent ebc2ee8ceb
commit dad07cc054
4 changed files with 26 additions and 16 deletions

View File

@ -259,17 +259,20 @@ enum class parse_error : uint_fast8_t {
template <typename UC> struct parsed_number_string_t {
am_mant_t mantissa{0};
am_pow_t exponent{0};
// contains the range of the significant digits
span<UC const> integer{}; // non-nullable
span<UC const> fraction{}; // nullable
UC const *lastmatch{nullptr};
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
bool negative{false};
#endif
bool invalid{false}; // be optimistic
bool too_many_digits{false}; // be optimistic
parse_error error{parse_error::no_error}; // be optimistic
am_pow_t exponent{0};
// contains the range of the significant digits
span<UC const> integer; // non-nullable
span<UC const> fraction; // nullable
UC const *lastmatch;
};
using byte_span = span<char const>;

View File

@ -31,14 +31,16 @@ compute_product_approximation(am_pow_t q, am_mant_t w) noexcept {
constexpr uint64_t precision_mask =
(bit_precision < 64) ? (uint64_t(0xFFFFFFFFFFFFFFFF) >> bit_precision)
: uint64_t(0xFFFFFFFFFFFFFFFF);
if ((firstproduct.high & precision_mask) ==
precision_mask) { // could further guard with (lower + w < lower)
// regarding the second product, we only need secondproduct.high, but our
// expectation is that the compiler will optimize this extra work away if
// needed.
value128 secondproduct =
value128 const secondproduct =
full_multiplication(w, powers::power_of_five_128[index + 1]);
firstproduct.low += secondproduct.high;
if (secondproduct.high > firstproduct.low) {
++firstproduct.high;
}
@ -62,7 +64,7 @@ namespace detail {
* where
* p = log(5**-q)/log(2) = -q * log(5)/log(2)
*/
constexpr fastfloat_really_inline am_pow_t power(am_pow_t q) noexcept {
constexpr fastfloat_really_inline am_pow_t power(am_pow_t const q) noexcept {
return (((152170 + 65536) * q) >> 16) + 63;
}
} // namespace detail
@ -103,9 +105,9 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
compute_float(am_pow_t q, am_mant_t w) noexcept {
adjusted_mantissa answer;
if ((w == 0) || (q < binary::smallest_power_of_ten())) {
// we want to get zero:
answer.power2 = 0;
answer.mantissa = 0;
// result should be zero
return answer;
}
if (q > binary::largest_power_of_ten()) {
@ -114,6 +116,7 @@ compute_float(am_pow_t q, am_mant_t w) noexcept {
answer.mantissa = 0;
return answer;
}
// At this point in time q is in [powers::smallest_power_of_five,
// powers::largest_power_of_five].
@ -127,7 +130,7 @@ compute_float(am_pow_t q, am_mant_t w) noexcept {
// 3. We might lose a bit due to the "upperbit" routine (result too small,
// requiring a shift)
value128 product =
value128 const product =
compute_product_approximation<binary::mantissa_explicit_bits() + 3>(q, w);
// The computed 'product' is always sufficient.
// Mathematical proof:
@ -141,6 +144,7 @@ compute_float(am_pow_t q, am_mant_t w) noexcept {
auto const upperbit = static_cast<am_bits_t>(product.high >> 63);
am_bits_t const shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3;
// Shift right the mantissa to the correct position
answer.mantissa = product.high >> shift;
answer.power2 = detail::power(q) + upperbit - lz - binary::minimum_exponent();
@ -192,6 +196,7 @@ compute_float(am_pow_t q, am_mant_t w) noexcept {
}
}
// Normal rounding
answer.mantissa += (answer.mantissa & 1); // round up
answer.mantissa >>= 1;
if (answer.mantissa >= (am_mant_t(2) << binary::mantissa_explicit_bits())) {
@ -199,6 +204,7 @@ compute_float(am_pow_t q, am_mant_t w) noexcept {
++answer.power2; // undo previous addition
}
// Check if we have infinity after computation
answer.mantissa &= ~(am_mant_t(1) << binary::mantissa_explicit_bits());
if (answer.power2 >= binary::infinite_power()) { // infinity
answer.power2 = binary::infinite_power();

View File

@ -110,10 +110,10 @@ template <typename UC> struct parse_options_t {
/** Which number formats are accepted */
chars_format format;
/** The character used as decimal point for floats */
UC decimal_point;
/** The base used for integers */
base_t base;
/** The character used as decimal point for floats */
UC decimal_point;
};
using parse_options = parse_options_t<char>;
@ -370,7 +370,7 @@ struct alignas(16) value128 {
constexpr value128(uint64_t _low, uint64_t _high) noexcept
: low(_low), high(_high) {}
constexpr value128() noexcept : low(0), high(0) {}
constexpr value128() noexcept {}
};
/* Helper C++14 constexpr generic implementation of leading_zeroes for 64-bit */
@ -415,7 +415,7 @@ leading_zeroes(uint64_t input_num) noexcept {
}
#ifdef FASTFLOAT_VISUAL_STUDIO
#if defined(_M_X64) || defined(_M_ARM64)
unsigned long leading_zero = 0;
unsigned long leading_zero;
// Search the mask data from most significant bit (MSB)
// to least significant bit (LSB) for a set bit (1).
_BitScanReverse64(&leading_zero, input_num);
@ -533,7 +533,7 @@ full_multiplication(uint64_t a, uint64_t b) noexcept {
struct alignas(16) adjusted_mantissa {
am_mant_t mantissa;
am_pow_t power2;
adjusted_mantissa() noexcept = default;
adjusted_mantissa() noexcept {};
constexpr bool operator==(adjusted_mantissa const &o) const noexcept {
return mantissa == o.mantissa && power2 == o.power2;

View File

@ -417,7 +417,7 @@ FASTFLOAT_CONSTEXPR20
integer_times_pow10(am_sign_mant_t const mantissa,
am_pow_t const decimal_exponent) noexcept {
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
const bool is_negative = mantissa < 0;
const auto is_negative = mantissa < 0;
const auto m = static_cast<am_mant_t>(is_negative ? -mantissa : mantissa);
#else
FASTFLOAT_ASSUME(mantissa >= 0);
@ -431,8 +431,9 @@ FASTFLOAT_CONSTEXPR20
value))
return value;
adjusted_mantissa am =
adjusted_mantissa const am =
compute_float<binary_format<double>>(decimal_exponent, m);
to_float(
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
is_negative,