diff --git a/include/fast_float/decimal_to_binary.h b/include/fast_float/decimal_to_binary.h index d84e716..8897420 100644 --- a/include/fast_float/decimal_to_binary.h +++ b/include/fast_float/decimal_to_binary.h @@ -17,7 +17,7 @@ namespace fast_float { // most significant bits and the low part corresponding to the least significant // bits. // -template +template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 value128 compute_product_approximation(int64_t q, uint64_t w) noexcept { int const index = 2 * int(q - powers::smallest_power_of_five); @@ -62,7 +62,7 @@ namespace detail { * where * p = log(5**-q)/log(2) = -q * log(5)/log(2) */ -constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { +constexpr fastfloat_really_inline am_pow_t power(am_pow_t q) noexcept { return (((152170 + 65536) * q) >> 16) + 63; } } // namespace detail @@ -72,11 +72,12 @@ constexpr fastfloat_really_inline int32_t power(int32_t q) noexcept { template fastfloat_really_inline FASTFLOAT_CONSTEXPR14 adjusted_mantissa compute_error_scaled(int64_t q, uint64_t w, int32_t lz) noexcept { - int32_t hilz = int32_t(w >> 63) ^ 1; + am_pow_t hilz = uint64_t(w >> 63) ^ 1; adjusted_mantissa answer; answer.mantissa = w << hilz; - int32_t bias = binary::mantissa_explicit_bits() - binary::minimum_exponent(); - answer.power2 = am_pow_t(detail::power(int32_t(q)) + bias - hilz - lz - 62 + + constexpr am_pow_t bias = + binary::mantissa_explicit_bits() - binary::minimum_exponent(); + answer.power2 = am_pow_t(detail::power(am_pow_t(q)) + bias - hilz - lz - 62 + invalid_am_bias); return answer; } @@ -86,7 +87,7 @@ compute_error_scaled(int64_t q, uint64_t w, int32_t lz) noexcept { template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa compute_error(int64_t q, uint64_t w) noexcept { - int lz = leading_zeroes(w); + limb_t lz = leading_zeroes(w); w <<= lz; value128 product = compute_product_approximation(q, w); @@ -118,7 +119,7 @@ compute_float(int64_t q, uint64_t w) noexcept { // powers::largest_power_of_five]. // We want the most significant bit of i to be 1. Shift if needed. - int lz = leading_zeroes(w); + limb_t lz = leading_zeroes(w); w <<= lz; // The required precision is binary::mantissa_explicit_bits() + 3 because @@ -138,12 +139,12 @@ compute_float(int64_t q, uint64_t w) noexcept { // branchless approach: value128 product = compute_product(q, w); but in // practice, we can win big with the compute_product_approximation if its // additional branch is easily predicted. Which is best is data specific. - int upperbit = int(product.high >> 63); - int shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3; + limb_t upperbit = limb_t(product.high >> 63); + limb_t shift = upperbit + 64 - binary::mantissa_explicit_bits() - 3; answer.mantissa = product.high >> shift; - answer.power2 = am_pow_t(detail::power(int32_t(q)) + upperbit - lz - + answer.power2 = am_pow_t(detail::power(am_pow_t(q)) + upperbit - lz - binary::minimum_exponent()); if (answer.power2 <= 0) { // we have a subnormal or very small value. // Here have that answer.power2 <= 0 so -answer.power2 >= 0 diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index 9d92201..b6983d8 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -68,8 +68,8 @@ to_extended(T const &value) noexcept { constexpr equiv_uint hidden_bit_mask = binary_format::hidden_bit_mask(); adjusted_mantissa am; - am_pow_t bias = binary_format::mantissa_explicit_bits() - - binary_format::minimum_exponent(); + constexpr am_pow_t bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); equiv_uint bits; #if FASTFLOAT_HAS_BIT_CAST bits = @@ -112,7 +112,8 @@ to_extended_halfway(T const &value) noexcept { template fastfloat_really_inline FASTFLOAT_CONSTEXPR14 void round(adjusted_mantissa &am, callback cb) noexcept { - am_pow_t mantissa_shift = 64 - binary_format::mantissa_explicit_bits() - 1; + constexpr am_pow_t mantissa_shift = + 64 - binary_format::mantissa_explicit_bits() - 1; if (-am.power2 >= mantissa_shift) { // have a denormal float am_pow_t shift = -am.power2 + 1; @@ -352,8 +353,8 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa positive_digit_comp( FASTFLOAT_ASSERT(bigmant.pow10(exponent)); bool truncated; am.mantissa = bigmant.hi64(truncated); - am_pow_t bias = binary_format::mantissa_explicit_bits() - - binary_format::minimum_exponent(); + constexpr am_pow_t bias = binary_format::mantissa_explicit_bits() - + binary_format::minimum_exponent(); am.power2 = bigmant.bit_length() - 64 + bias; round(am, [truncated](adjusted_mantissa &a, am_pow_t shift) { diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index bd952ee..e161b6e 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -445,8 +445,8 @@ full_multiplication(uint64_t a, uint64_t b) noexcept { // Value of the mantissa. typedef uint_fast64_t am_mant_t; -// Size of bits in the mantissa. -typedef uint_fast8_t am_bits_t; +// Size of bits in the mantissa and path and roundings shifts +typedef int_fast8_t am_bits_t; // Power bias is signed for handling a denormal float // or an invalid mantissa. @@ -481,17 +481,17 @@ template struct binary_format : binary_format_lookup_tables { static constexpr am_pow_t minimum_exponent(); static constexpr am_pow_t infinite_power(); static constexpr am_bits_t sign_index(); - static constexpr am_pow_t + static constexpr am_bits_t min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST - static constexpr am_pow_t max_exponent_fast_path(); - static constexpr am_pow_t max_exponent_round_to_even(); - static constexpr am_pow_t min_exponent_round_to_even(); - static constexpr equiv_uint max_mantissa_fast_path(int64_t power); + static constexpr am_bits_t max_exponent_fast_path(); + static constexpr am_bits_t max_exponent_round_to_even(); + static constexpr am_bits_t min_exponent_round_to_even(); + static constexpr equiv_uint max_mantissa_fast_path(am_pow_t power); static constexpr equiv_uint max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST static constexpr am_pow_t largest_power_of_ten(); static constexpr am_pow_t smallest_power_of_ten(); - static constexpr T exact_power_of_ten(int64_t power); + static constexpr T exact_power_of_ten(am_pow_t power); static constexpr am_digits max_digits(); static constexpr equiv_uint exponent_mask(); static constexpr equiv_uint mantissa_mask(); @@ -582,7 +582,7 @@ constexpr uint32_t binary_format_lookup_tables::max_mantissa[]; #endif template <> -inline constexpr am_pow_t binary_format::min_exponent_fast_path() { +inline constexpr am_bits_t binary_format::min_exponent_fast_path() { #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) return 0; #else @@ -591,7 +591,7 @@ inline constexpr am_pow_t binary_format::min_exponent_fast_path() { } template <> -inline constexpr am_pow_t binary_format::min_exponent_fast_path() { +inline constexpr am_bits_t binary_format::min_exponent_fast_path() { #if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0) return 0; #else @@ -610,22 +610,22 @@ inline constexpr am_bits_t binary_format::mantissa_explicit_bits() { } template <> -inline constexpr am_pow_t binary_format::max_exponent_round_to_even() { +inline constexpr am_bits_t binary_format::max_exponent_round_to_even() { return 23; } template <> -inline constexpr am_pow_t binary_format::max_exponent_round_to_even() { +inline constexpr am_bits_t binary_format::max_exponent_round_to_even() { return 10; } template <> -inline constexpr am_pow_t binary_format::min_exponent_round_to_even() { +inline constexpr am_bits_t binary_format::min_exponent_round_to_even() { return -4; } template <> -inline constexpr am_pow_t binary_format::min_exponent_round_to_even() { +inline constexpr am_bits_t binary_format::min_exponent_round_to_even() { return -17; } @@ -659,12 +659,12 @@ template <> inline constexpr am_bits_t binary_format::sign_index() { #endif template <> -inline constexpr am_pow_t binary_format::max_exponent_fast_path() { +inline constexpr am_bits_t binary_format::max_exponent_fast_path() { return 22; } template <> -inline constexpr am_pow_t binary_format::max_exponent_fast_path() { +inline constexpr am_bits_t binary_format::max_exponent_fast_path() { return 10; } @@ -704,7 +704,7 @@ constexpr uint16_t template <> inline constexpr std::float16_t -binary_format::exact_power_of_ten(int64_t power) { +binary_format::exact_power_of_ten(am_pow_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)powers_of_ten[0], powers_of_ten[power]; } @@ -728,52 +728,52 @@ binary_format::hidden_bit_mask() { } template <> -inline constexpr int8_t +inline constexpr am_bits_t binary_format::max_exponent_fast_path() { return 4; } template <> -inline constexpr uint8_t +inline constexpr am_bits_t binary_format::mantissa_explicit_bits() { return 10; } template <> -inline constexpr uint64_t -binary_format::max_mantissa_fast_path(int64_t power) { +inline constexpr binary_format::equiv_uint +binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that - // power >= 0 && power <= 4 + FASTFLOAT_ASSUME(power >= 0 && power <= 4); // // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; } template <> -inline constexpr int8_t +inline constexpr am_bits_t binary_format::min_exponent_fast_path() { return 0; } template <> -inline constexpr int16_t +inline constexpr am_bits_t binary_format::max_exponent_round_to_even() { return 5; } template <> -inline constexpr int16_t +inline constexpr am_bits_t binary_format::min_exponent_round_to_even() { return -22; } template <> -inline constexpr am_exp_t binary_format::minimum_exponent() { +inline constexpr am_pow_t binary_format::minimum_exponent() { return -15; } template <> -inline constexpr am_exp_t binary_format::infinite_power() { +inline constexpr am_pow_t binary_format::infinite_power() { return 0x1F; } @@ -787,13 +787,13 @@ inline constexpr am_bits_t binary_format::sign_index() { #endif template <> -inline constexpr am_exp_t +inline constexpr am_pow_t binary_format::largest_power_of_ten() { return 4; } template <> -inline constexpr am_exp_t +inline constexpr am_pow_t binary_format::smallest_power_of_ten() { return -27; } @@ -812,7 +812,7 @@ template struct binary_format_lookup_tables { // Largest integer value v so that (5**index * v) <= 1<<8. // 0x100 == 1<<8 - static constexpr uint64_t max_mantissa[] = {0x100, 0x100 / 5, 0x100 / (5 * 5), + static constexpr uint16_t max_mantissa[] = {0x100, 0x100 / 5, 0x100 / (5 * 5), 0x100 / (5 * 5 * 5), 0x100 / (5 * 5 * 5 * 5)}; }; @@ -831,13 +831,13 @@ constexpr uint64_t template <> inline constexpr std::bfloat16_t -binary_format::exact_power_of_ten(int64_t power) { +binary_format::exact_power_of_ten(am_pow_t power) { // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)powers_of_ten[0], powers_of_ten[power]; } template <> -inline constexpr int8_t +inline constexpr am_bits_t binary_format::max_exponent_fast_path() { return 3; } @@ -861,66 +861,66 @@ binary_format::hidden_bit_mask() { } template <> -inline constexpr uint8_t +inline constexpr am_bits_t binary_format::mantissa_explicit_bits() { return 7; } template <> -inline constexpr uint64_t -binary_format::max_mantissa_fast_path(int64_t power) { +inline constexpr binary_format::equiv_uint +binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that - // power >= 0 && power <= 3 + FASTFLOAT_ASSUME(power >= 0 && power <= 3); // // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; } template <> -inline constexpr int8_t +inline constexpr am_bits_t binary_format::min_exponent_fast_path() { return 0; } template <> -inline constexpr am_exp_t +inline constexpr am_bits_t binary_format::max_exponent_round_to_even() { return 3; } template <> -inline constexpr am_exp_t +inline constexpr am_bits_t binary_format::min_exponent_round_to_even() { return -24; } template <> -inline constexpr am_exp_t binary_format::minimum_exponent() { +inline constexpr am_pow_t binary_format::minimum_exponent() { return -127; } template <> -inline constexpr am_exp_t binary_format::infinite_power() { +inline constexpr am_pow_t binary_format::infinite_power() { return 0xFF; } #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN template <> -inline constexpr uint8_t binary_format::sign_index() { +inline constexpr am_bits_t binary_format::sign_index() { return 15; } #endif template <> -inline constexpr am_exp_t +inline constexpr am_pow_t binary_format::largest_power_of_ten() { return 38; } template <> -inline constexpr am_exp_t +inline constexpr am_pow_t binary_format::smallest_power_of_ten() { return -60; } @@ -932,8 +932,8 @@ inline constexpr uint16_t binary_format::max_digits() { #endif // __STDCPP_BFLOAT16_T__ template <> -inline constexpr uint64_t -binary_format::max_mantissa_fast_path(int64_t power) { +inline constexpr binary_format::equiv_uint +binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that FASTFLOAT_ASSUME(power >= 0 && power <= 22); // @@ -942,8 +942,8 @@ binary_format::max_mantissa_fast_path(int64_t power) { } template <> -inline constexpr uint32_t -binary_format::max_mantissa_fast_path(int64_t power) { +inline constexpr binary_format::equiv_uint +binary_format::max_mantissa_fast_path(am_pow_t power) { // caller is responsible to ensure that FASTFLOAT_ASSUME(power >= 0 && power <= 10); // @@ -953,7 +953,7 @@ binary_format::max_mantissa_fast_path(int64_t power) { template <> inline constexpr double -binary_format::exact_power_of_ten(int64_t power) { +binary_format::exact_power_of_ten(am_pow_t power) { // caller is responsible to ensure that FASTFLOAT_ASSUME(power >= 0 && power <= 22); // @@ -962,7 +962,8 @@ binary_format::exact_power_of_ten(int64_t power) { } template <> -inline constexpr float binary_format::exact_power_of_ten(int64_t power) { +inline constexpr float +binary_format::exact_power_of_ten(am_pow_t power) { // caller is responsible to ensure that FASTFLOAT_ASSUME(power >= 0 && power <= 10); //