mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-07 01:06:48 +08:00
Merge pull request #200 from leni536/fix_static_tables
Make tables external linkage
This commit is contained in:
commit
ff77380a76
@ -252,16 +252,43 @@ 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_lookup_tables<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
|
template <typename T, typename U = void>
|
||||||
constexpr static uint64_t max_mantissa_double[] = {
|
struct binary_format_lookup_tables;
|
||||||
|
|
||||||
|
template <typename T> struct binary_format : binary_format_lookup_tables<T> {
|
||||||
|
using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
|
||||||
|
|
||||||
|
static inline constexpr int mantissa_explicit_bits();
|
||||||
|
static inline constexpr int minimum_exponent();
|
||||||
|
static inline constexpr int infinite_power();
|
||||||
|
static inline constexpr int sign_index();
|
||||||
|
static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
|
||||||
|
static inline constexpr int max_exponent_fast_path();
|
||||||
|
static inline constexpr int max_exponent_round_to_even();
|
||||||
|
static inline constexpr int min_exponent_round_to_even();
|
||||||
|
static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
|
||||||
|
static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
|
||||||
|
static inline constexpr int largest_power_of_ten();
|
||||||
|
static inline constexpr int smallest_power_of_ten();
|
||||||
|
static inline constexpr T exact_power_of_ten(int64_t power);
|
||||||
|
static inline constexpr size_t max_digits();
|
||||||
|
static inline constexpr equiv_uint exponent_mask();
|
||||||
|
static inline constexpr equiv_uint mantissa_mask();
|
||||||
|
static inline constexpr equiv_uint hidden_bit_mask();
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
struct binary_format_lookup_tables<double, U> {
|
||||||
|
static constexpr 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};
|
||||||
|
|
||||||
|
// Largest integer value v so that (5**index * v) <= 1<<53.
|
||||||
|
// 0x10000000000000 == 1 << 53
|
||||||
|
static constexpr uint64_t max_mantissa[] = {
|
||||||
0x10000000000000,
|
0x10000000000000,
|
||||||
0x10000000000000 / 5,
|
0x10000000000000 / 5,
|
||||||
0x10000000000000 / (5 * 5),
|
0x10000000000000 / (5 * 5),
|
||||||
@ -286,44 +313,42 @@ constexpr static uint64_t max_mantissa_double[] = {
|
|||||||
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 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),
|
||||||
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)};
|
0x10000000000000 / (constant_55555 * constant_55555 * constant_55555 * constant_55555 * 5 * 5 * 5 * 5)};
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr double binary_format_lookup_tables<double, U>::powers_of_ten[];
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr uint64_t binary_format_lookup_tables<double, U>::max_mantissa[];
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
struct binary_format_lookup_tables<float, U> {
|
||||||
|
static constexpr float powers_of_ten[] = {1e0f, 1e1f, 1e2f, 1e3f, 1e4f, 1e5f,
|
||||||
|
1e6f, 1e7f, 1e8f, 1e9f, 1e10f};
|
||||||
|
|
||||||
// Largest integer value v so that (5**index * v) <= 1<<24.
|
// Largest integer value v so that (5**index * v) <= 1<<24.
|
||||||
// 0x1000000 == 1<<24
|
// 0x1000000 == 1<<24
|
||||||
constexpr static uint64_t max_mantissa_float[] = {
|
static constexpr uint64_t max_mantissa[] = {
|
||||||
0x1000000,
|
0x1000000,
|
||||||
0x1000000 / 5,
|
0x1000000 / 5,
|
||||||
0x1000000 / (5 * 5),
|
0x1000000 / (5 * 5),
|
||||||
0x1000000 / (5 * 5 * 5),
|
0x1000000 / (5 * 5 * 5),
|
||||||
0x1000000 / (5 * 5 * 5 * 5),
|
0x1000000 / (5 * 5 * 5 * 5),
|
||||||
0x1000000 / (constant_55555),
|
0x1000000 / (constant_55555),
|
||||||
0x1000000 / (constant_55555 * 5),
|
0x1000000 / (constant_55555 * 5),
|
||||||
0x1000000 / (constant_55555 * 5 * 5),
|
0x1000000 / (constant_55555 * 5 * 5),
|
||||||
0x1000000 / (constant_55555 * 5 * 5 * 5),
|
0x1000000 / (constant_55555 * 5 * 5 * 5),
|
||||||
0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
|
0x1000000 / (constant_55555 * 5 * 5 * 5 * 5),
|
||||||
0x1000000 / (constant_55555 * constant_55555),
|
0x1000000 / (constant_55555 * constant_55555),
|
||||||
0x1000000 / (constant_55555 * constant_55555 * 5)};
|
0x1000000 / (constant_55555 * constant_55555 * 5)};
|
||||||
|
|
||||||
template <typename T> struct binary_format {
|
|
||||||
using equiv_uint = typename std::conditional<sizeof(T) == 4, uint32_t, uint64_t>::type;
|
|
||||||
|
|
||||||
static inline constexpr int mantissa_explicit_bits();
|
|
||||||
static inline constexpr int minimum_exponent();
|
|
||||||
static inline constexpr int infinite_power();
|
|
||||||
static inline constexpr int sign_index();
|
|
||||||
static inline constexpr int min_exponent_fast_path(); // used when fegetround() == FE_TONEAREST
|
|
||||||
static inline constexpr int max_exponent_fast_path();
|
|
||||||
static inline constexpr int max_exponent_round_to_even();
|
|
||||||
static inline constexpr int min_exponent_round_to_even();
|
|
||||||
static inline constexpr uint64_t max_mantissa_fast_path(int64_t power);
|
|
||||||
static inline constexpr uint64_t max_mantissa_fast_path(); // used when fegetround() == FE_TONEAREST
|
|
||||||
static inline constexpr int largest_power_of_ten();
|
|
||||||
static inline constexpr int smallest_power_of_ten();
|
|
||||||
static inline constexpr T exact_power_of_ten(int64_t power);
|
|
||||||
static inline constexpr size_t max_digits();
|
|
||||||
static inline constexpr equiv_uint exponent_mask();
|
|
||||||
static inline constexpr equiv_uint mantissa_mask();
|
|
||||||
static inline constexpr equiv_uint hidden_bit_mask();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr float binary_format_lookup_tables<float, U>::powers_of_ten[];
|
||||||
|
|
||||||
|
template <typename U>
|
||||||
|
constexpr uint64_t binary_format_lookup_tables<float, U>::max_mantissa[];
|
||||||
|
|
||||||
template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
|
template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
|
||||||
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
||||||
return 0;
|
return 0;
|
||||||
@ -386,6 +411,7 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 +419,8 @@ 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];
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
|
return (void)max_mantissa[0], 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 +429,19 @@ 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];
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
|
return (void)max_mantissa[0], max_mantissa[power];
|
||||||
}
|
}
|
||||||
|
|
||||||
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];
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
|
return (void)powers_of_ten[0], 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) {
|
||||||
|
// Work around clang bug https://godbolt.org/z/zedh7rrhc
|
||||||
return powers_of_ten_float[power];
|
return (void)powers_of_ten[0], powers_of_ten[power];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user