Make lookup tables external linkage

This commit is contained in:
Lenard Szolnoki 2023-05-07 23:07:34 +01:00
parent fe571b1da7
commit cc042ae409

View File

@ -252,55 +252,8 @@ struct adjusted_mantissa {
// Bias so we can get the real exponent with an invalid 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 int32_t invalid_am_bias = -0x8000;
constexpr static double powers_of_ten_double[] = { // used for binary_format<T>::max_mantissa
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
constexpr uint64_t constant_55555 = 5 * 5 * 5 * 5 * 5; 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 <typename T> struct binary_format { template <typename T> struct binary_format {
using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type; using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
@ -322,6 +275,9 @@ template <typename T> struct binary_format {
static inline constexpr equiv_uint exponent_mask(); static inline constexpr equiv_uint exponent_mask();
static inline constexpr equiv_uint mantissa_mask(); static inline constexpr equiv_uint mantissa_mask();
static inline constexpr equiv_uint hidden_bit_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<double>::min_exponent_fast_path() { template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
@ -386,6 +342,52 @@ template <> inline constexpr int binary_format<double>::max_exponent_fast_path()
template <> inline constexpr int binary_format<float>::max_exponent_fast_path() { template <> inline constexpr int binary_format<float>::max_exponent_fast_path() {
return 10; return 10;
} }
// Largest integer value v so that (5**index * v) <= 1<<53.
// 0x10000000000000 == 1 << 53
template <>
constexpr uint64_t binary_format<double>::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<float>::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<double>::max_mantissa_fast_path() { template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path() {
return uint64_t(2) << mantissa_explicit_bits(); return uint64_t(2) << mantissa_explicit_bits();
} }
@ -393,7 +395,7 @@ template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_p
// caller is responsible to ensure that // caller is responsible to ensure that
// power >= 0 && power <= 22 // power >= 0 && power <= 22
// //
return max_mantissa_double[power]; return max_mantissa[power];
} }
template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() { template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
return uint64_t(2) << mantissa_explicit_bits(); return uint64_t(2) << mantissa_explicit_bits();
@ -402,17 +404,25 @@ template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_pa
// caller is responsible to ensure that // caller is responsible to ensure that
// power >= 0 && power <= 10 // power >= 0 && power <= 10
// //
return max_mantissa_float[power]; return max_mantissa[power];
} }
template <>
constexpr double binary_format<double>::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<float>::powers_of_ten[] = {
1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f, 1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
template <> template <>
inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) { inline constexpr double binary_format<double>::exact_power_of_ten(int64_t power) {
return powers_of_ten_double[power]; return powers_of_ten[power];
} }
template <> template <>
inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) { inline constexpr float binary_format<float>::exact_power_of_ten(int64_t power) {
return powers_of_ten[power];
return powers_of_ten_float[power];
} }