From 8cee0250828d682d0405221c02b83b53dc564919 Mon Sep 17 00:00:00 2001 From: Anders Dalvander Date: Sun, 1 Dec 2024 20:03:47 +0100 Subject: [PATCH] add powers_of_ten/max_mantissa for float16_t/bfloat16_t --- include/fast_float/float_common.h | 37 ++++++++++++++++++++++++------- 1 file changed, 29 insertions(+), 8 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 8267347..9b59735 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -713,8 +713,17 @@ inline constexpr uint64_t binary_format::max_mantissa_fast_path() { // credit: Jakub Jelínek #ifdef __STDCPP_FLOAT16_T__ template struct binary_format_lookup_tables { - static constexpr std::float16_t powers_of_ten[] = {1}; // todo: fix this - static constexpr uint64_t max_mantissa[] = {1}; // todo: fix this + static constexpr std::float16_t powers_of_ten[] = {1e0f16, 1e1f16, 1e2f16, + 1e3f16, 1e4f16}; + + // Largest integer value v so that (5**index * v) <= 1<<11. + // 0x800 == 1<<11 + static constexpr uint64_t max_mantissa[] = {0x800, + 0x800 / 5, + 0x800 / (5 * 5), + 0x800 / (5 * 5 * 5), + 0x800 / (5 * 5 * 5 * 5), + 0x800 / (constant_55555)}; }; #if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE @@ -756,18 +765,21 @@ binary_format::hidden_bit_mask() { template <> inline constexpr int binary_format::max_exponent_fast_path() { - return 0; + return 4; } template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { - return 0; + return uint64_t(2) << mantissa_explicit_bits(); } template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 4 + // // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; } @@ -823,8 +835,14 @@ template <> constexpr size_t binary_format::max_digits() { // credit: Jakub Jelínek #ifdef __STDCPP_BFLOAT16_T__ template struct binary_format_lookup_tables { - static constexpr std::bfloat16_t powers_of_ten[] = {1}; // todo: fix this - static constexpr uint64_t max_mantissa[] = {1}; // todo: fix this + static constexpr std::bfloat16_t powers_of_ten[] = {1e0bf16, 1e1bf16, 1e2bf16, + 1e3bf16}; + + // 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), + 0x100 / (5 * 5 * 5), + 0x100 / (5 * 5 * 5 * 5)}; }; #if FASTFLOAT_DETAIL_MUST_DEFINE_CONSTEXPR_VARIABLE @@ -848,7 +866,7 @@ binary_format::exact_power_of_ten(int64_t power) { template <> inline constexpr int binary_format::max_exponent_fast_path() { - return 0; + return 3; } template <> @@ -872,12 +890,15 @@ binary_format::hidden_bit_mask() { template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { - return 0; + return uint64_t(2) << mantissa_explicit_bits(); } template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path(int64_t power) { + // caller is responsible to ensure that + // power >= 0 && power <= 3 + // // Work around clang bug https://godbolt.org/z/zedh7rrhc return (void)max_mantissa[0], max_mantissa[power]; }