diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index bf35604..01ad6ac 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -435,7 +435,7 @@ parse_number_string(UC const *p, UC const *pend, } else { // Now let's parse the explicit exponent. while ((p != pend) && is_integer(*p)) { - if (exp_number < std::numeric_limits::max()) { + if (exp_number < am_bias_limit) { // check for exponent overflow if we have too many digits. auto const digit = uint8_t(*p - UC('0')); exp_number = 10 * exp_number + digit; @@ -561,7 +561,7 @@ parse_int_string(UC const *p, UC const *pend, T &value, auto const *const start_digits = p; FASTFLOAT_IF_CONSTEXPR17((std::is_same::value)) { - const size_t len = (size_t)(pend - p); + const auto len = static_cast(pend - p); if (len == 0) { if (has_leading_zeros) { value = 0; @@ -581,7 +581,7 @@ parse_int_string(UC const *p, UC const *pend, T &value, if (cpp20_and_in_constexpr()) { digits.as_int = 0; - for (size_t j = 0; j < 4 && j < len; ++j) { + for (uint_fast8_t j = 0; j < 4 && j < len; ++j) { digits.as_str[j] = static_cast(p[j]); } } else if (len >= 4) { @@ -598,12 +598,13 @@ parse_int_string(UC const *p, UC const *pend, T &value, #endif } - uint32_t magic = + const uint32_t magic = ((digits.as_int + 0x46464646u) | (digits.as_int - 0x30303030u)) & 0x80808080u; - uint32_t tz = (uint32_t)countr_zero_32(magic); // 7, 15, 23, 31, or 32 + const auto tz = + static_cast(countr_zero_32(magic)); // 7, 15, 23, 31, or 32 uint32_t nd = (tz == 32) ? 4 : (tz >> 3); - nd = (uint32_t)std::min((size_t)nd, len); + nd = std::min(nd, len); if (nd == 0) { if (has_leading_zeros) { value = 0; @@ -617,7 +618,7 @@ parse_int_string(UC const *p, UC const *pend, T &value, } if (nd > 3) { const UC *q = p + nd; - size_t rem = len - nd; + uint_fast8_t rem = len - nd; while (rem) { if (*q < UC('0') || *q > UC('9')) break; @@ -632,15 +633,15 @@ parse_int_string(UC const *p, UC const *pend, T &value, digits.as_int ^= 0x30303030u; digits.as_int <<= ((4 - nd) * 8); - uint32_t check = ((digits.as_int >> 24) & 0xff) | - ((digits.as_int >> 8) & 0xff00) | - ((digits.as_int << 8) & 0xff0000); + const uint32_t check = ((digits.as_int >> 24) & 0xff) | + ((digits.as_int >> 8) & 0xff00) | + ((digits.as_int << 8) & 0xff0000); if (check > 0x00020505) { answer.ec = std::errc::result_out_of_range; answer.ptr = p + nd; return answer; } - value = (uint8_t)((0x640a01 * digits.as_int) >> 24); + value = static_cast((0x640a01 * digits.as_int) >> 24); answer.ec = std::errc(); answer.ptr = p + nd; return answer; diff --git a/include/fast_float/fast_float.h b/include/fast_float/fast_float.h index 8540e78..bfef022 100644 --- a/include/fast_float/fast_float.h +++ b/include/fast_float/fast_float.h @@ -59,11 +59,11 @@ from_chars_advanced(UC const *first, UC const *last, T &value, * `new` or `malloc`). */ FASTFLOAT_CONSTEXPR20 inline double -integer_times_pow10(uint64_t const mantissa, - int_fast16_t const decimal_exponent) noexcept; +integer_times_pow10(am_mant_t const mantissa, + am_pow_t const decimal_exponent) noexcept; FASTFLOAT_CONSTEXPR20 inline double -integer_times_pow10(int64_t const mantissa, - int_fast16_t const decimal_exponent) noexcept; +integer_times_pow10(am_sign_mant_t const mantissa, + am_pow_t const decimal_exponent) noexcept; /** * This function is a template overload of `integer_times_pow10()` @@ -73,13 +73,13 @@ integer_times_pow10(int64_t const mantissa, template FASTFLOAT_CONSTEXPR20 typename std::enable_if::value, T>::type - integer_times_pow10(uint64_t const mantissa, - int_fast16_t const decimal_exponent) noexcept; + integer_times_pow10(am_mant_t const mantissa, + am_pow_t const decimal_exponent) noexcept; template FASTFLOAT_CONSTEXPR20 typename std::enable_if::value, T>::type - integer_times_pow10(int64_t const mantissa, - int_fast16_t const decimal_exponent) noexcept; + integer_times_pow10(am_sign_mant_t const mantissa, + am_pow_t const decimal_exponent) noexcept; /** * from_chars for integer types. diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 763f799..ad3e7dc 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -500,18 +500,24 @@ full_multiplication(uint64_t a, uint64_t b) noexcept { return answer; } -// Value of the mantissa. An unsigned int avoids signed overflows (which are -// bad) +// 64 bit integer is used because mantissa can be up to 53 bits for double. +// Value of the int mantissa in the API. +typedef int_fast64_t am_sign_mant_t; +// An unsigned int avoids signed overflows (which are bad) typedef uint_fast64_t am_mant_t; + // Size of bits in the mantissa and path and rounding shifts typedef int_fast8_t am_bits_t; +// 16 bit signed integer is used for power to cover all double exponents. // Power bias is signed for handling a denormal float // or an invalid mantissa. -typedef int_fast64_t am_pow_t; - +typedef int_fast16_t am_pow_t; // Bias so we can get the real exponent with an invalid adjusted_mantissa. -constexpr static am_pow_t invalid_am_bias = -0x8000; +constexpr static am_pow_t invalid_am_bias = + std::numeric_limits::min() + 1; +constexpr static am_pow_t am_bias_limit = + (std::numeric_limits::max() + 1) / 8; struct alignas(16) adjusted_mantissa { am_mant_t mantissa;