From cc042ae40958cd6646585d950d3cb10ad6e39a0b Mon Sep 17 00:00:00 2001 From: Lenard Szolnoki Date: Sun, 7 May 2023 23:07:34 +0100 Subject: [PATCH] Make lookup tables external linkage --- include/fast_float/float_common.h | 116 ++++++++++++++++-------------- 1 file changed, 63 insertions(+), 53 deletions(-) diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index 6901d7c..007dab3 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -252,55 +252,8 @@ struct adjusted_mantissa { // Bias so we can get the real exponent with an invalid adjusted_mantissa. constexpr static int32_t invalid_am_bias = -0x8000; -constexpr static double powers_of_ten_double[] = { - 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, - 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; -constexpr static float powers_of_ten_float[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, - 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; -// used for max_mantissa_double and max_mantissa_float +// used for binary_format::max_mantissa constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; -// Largest integer value v so that (5**index * v) <= 1<<53. -// 0x10000000000000 == 1 << 53 -constexpr static uint64_t max_mantissa_double[] = { - 0x10000000000000, - 0x10000000000000 / 5, - 0x10000000000000 / (5 * 5), - 0x10000000000000 / (5 * 5 * 5), - 0x10000000000000 / (5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555), - 0x10000000000000 / (constant_55555 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), - 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)}; - // Largest integer value v so that (5**index * v) <= 1<<24. - // 0x1000000 == 1<<24 - constexpr static uint64_t max_mantissa_float[] = { - 0x1000000, - 0x1000000 / 5, - 0x1000000 / (5 * 5), - 0x1000000 / (5 * 5 * 5), - 0x1000000 / (5 * 5 * 5 * 5), - 0x1000000 / (constant_55555), - 0x1000000 / (constant_55555 * 5), - 0x1000000 / (constant_55555 * 5 * 5), - 0x1000000 / (constant_55555 * 5 * 5 * 5), - 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), - 0x1000000 / (constant_55555 * constant_55555), - 0x1000000 / (constant_55555 * constant_55555 * 5)}; template struct binary_format { using equiv_uint = typename std::conditional::type; @@ -322,6 +275,9 @@ template struct binary_format { static inline constexpr equiv_uint exponent_mask(); static inline constexpr equiv_uint mantissa_mask(); static inline constexpr equiv_uint hidden_bit_mask(); + + static const T powers_of_ten[]; + static const uint64_t max_mantissa[]; }; template <> inline constexpr int binary_format::min_exponent_fast_path() { @@ -386,6 +342,52 @@ template <> inline constexpr int binary_format::max_exponent_fast_path() template <> inline constexpr int binary_format::max_exponent_fast_path() { return 10; } + +// Largest integer value v so that (5**index * v) <= 1<<53. +// 0x10000000000000 == 1 << 53 +template <> +constexpr uint64_t binary_format::max_mantissa[] = { + 0x10000000000000, + 0x10000000000000 / 5, + 0x10000000000000 / (5 * 5), + 0x10000000000000 / (5 * 5 * 5), + 0x10000000000000 / (5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555), + 0x10000000000000 / (constant_55555 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5), + 0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)}; +// Largest integer value v so that (5**index * v) <= 1<<24. +// 0x1000000 == 1<<24 +template <> +constexpr uint64_t binary_format::max_mantissa[] = { + 0x1000000, + 0x1000000 / 5, + 0x1000000 / (5 * 5), + 0x1000000 / (5 * 5 * 5), + 0x1000000 / (5 * 5 * 5 * 5), + 0x1000000 / (constant_55555), + 0x1000000 / (constant_55555 * 5), + 0x1000000 / (constant_55555 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * 5 * 5 * 5 * 5), + 0x1000000 / (constant_55555 * constant_55555), + 0x1000000 / (constant_55555 * constant_55555 * 5)}; + template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); } @@ -393,7 +395,7 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_p // caller is responsible to ensure that // power >= 0 && power <= 22 // - return max_mantissa_double[power]; + return max_mantissa[power]; } template <> inline constexpr uint64_t binary_format::max_mantissa_fast_path() { return uint64_t(2) << mantissa_explicit_bits(); @@ -402,17 +404,25 @@ template <> inline constexpr uint64_t binary_format::max_mantissa_fast_pa // caller is responsible to ensure that // power >= 0 && power <= 10 // - return max_mantissa_float[power]; + return max_mantissa[power]; } +template <> +constexpr double binary_format::powers_of_ten[] = { + 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11, + 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22}; + +template <> +constexpr float binary_format::powers_of_ten[] = { + 1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f, 1e7f, 1e8f, 1e9f, 1e10f}; + template <> inline constexpr double binary_format::exact_power_of_ten(int64_t power) { - return powers_of_ten_double[power]; + return powers_of_ten[power]; } template <> inline constexpr float binary_format::exact_power_of_ten(int64_t power) { - - return powers_of_ten_float[power]; + return powers_of_ten[power]; }