mirror of
https://github.com/fastfloat/fast_float.git
synced 2026-02-08 02:36:44 +08:00
We might reenable clinger.
This commit is contained in:
parent
dac641ee13
commit
6ceb29a7e4
@ -272,10 +272,12 @@ template <typename T> struct binary_format {
|
|||||||
static inline constexpr int minimum_exponent();
|
static inline constexpr int minimum_exponent();
|
||||||
static inline constexpr int infinite_power();
|
static inline constexpr int infinite_power();
|
||||||
static inline constexpr int sign_index();
|
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_fast_path();
|
||||||
static inline constexpr int max_exponent_round_to_even();
|
static inline constexpr int max_exponent_round_to_even();
|
||||||
static inline constexpr int min_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(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 largest_power_of_ten();
|
||||||
static inline constexpr int smallest_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 T exact_power_of_ten(int64_t power);
|
||||||
@ -285,6 +287,22 @@ template <typename T> struct binary_format {
|
|||||||
static inline constexpr equiv_uint hidden_bit_mask();
|
static inline constexpr equiv_uint hidden_bit_mask();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <> inline constexpr int binary_format<double>::min_exponent_fast_path() {
|
||||||
|
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return -22;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> inline constexpr int binary_format<float>::min_exponent_fast_path() {
|
||||||
|
#if (FLT_EVAL_METHOD != 1) && (FLT_EVAL_METHOD != 0)
|
||||||
|
return 0;
|
||||||
|
#else
|
||||||
|
return -10;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
|
template <> inline constexpr int binary_format<double>::mantissa_explicit_bits() {
|
||||||
return 52;
|
return 52;
|
||||||
}
|
}
|
||||||
@ -331,13 +349,18 @@ 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() {
|
||||||
|
return uint64_t(2) << mantissa_explicit_bits();
|
||||||
|
}
|
||||||
template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
|
template <> inline constexpr uint64_t binary_format<double>::max_mantissa_fast_path(int64_t power) {
|
||||||
// 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_double[power];
|
||||||
}
|
}
|
||||||
|
template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path() {
|
||||||
|
return uint64_t(2) << mantissa_explicit_bits();
|
||||||
|
}
|
||||||
template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
|
template <> inline constexpr uint64_t binary_format<float>::max_mantissa_fast_path(int64_t power) {
|
||||||
// caller is responsible to ensure that
|
// caller is responsible to ensure that
|
||||||
// power >= 0 && power <= 10
|
// power >= 0 && power <= 10
|
||||||
|
|||||||
@ -60,6 +60,15 @@ from_chars_result parse_infnan(const char *first, const char *last, T &value) n
|
|||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fastfloat_really_inline bool rounds_nearest() {
|
||||||
|
// This function is meant to be equivalent to :
|
||||||
|
// prior: #include <cfenv>
|
||||||
|
// return fegetround() == FE_TONEAREST;
|
||||||
|
// volatile prevents the compiler from computing the function at compile-time
|
||||||
|
static volatile float fmin = std::numeric_limits<float>::min();
|
||||||
|
return (fmin + 1.0f == 1.0f - fmin);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
@ -87,12 +96,25 @@ from_chars_result from_chars_advanced(const char *first, const char *last,
|
|||||||
}
|
}
|
||||||
answer.ec = std::errc(); // be optimistic
|
answer.ec = std::errc(); // be optimistic
|
||||||
answer.ptr = pns.lastmatch;
|
answer.ptr = pns.lastmatch;
|
||||||
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's proposal
|
if(detail::rounds_nearest()) {
|
||||||
if (pns.exponent >= 0 && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent) && !pns.too_many_digits) {
|
// We have that fegetround() == FE_TONEAREST.
|
||||||
value = T(pns.mantissa);
|
// Next is Clinger's fast path.
|
||||||
value = value * binary_format<T>::exact_power_of_ten(pns.exponent);
|
if (binary_format<T>::min_exponent_fast_path() <= pns.exponent && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path() && !pns.too_many_digits) {
|
||||||
if (pns.negative) { value = -value; }
|
value = T(pns.mantissa);
|
||||||
return answer;
|
if (pns.exponent < 0) { value = value / binary_format<T>::exact_power_of_ten(-pns.exponent); }
|
||||||
|
else { value = value * binary_format<T>::exact_power_of_ten(pns.exponent); }
|
||||||
|
if (pns.negative) { value = -value; }
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// We do not have that fegetround() == FE_TONEAREST.
|
||||||
|
// Next is a modified Clinger's fast path, inspired by Jakub Jelínek's proposal
|
||||||
|
if (pns.exponent >= 0 && pns.exponent <= binary_format<T>::max_exponent_fast_path() && pns.mantissa <=binary_format<T>::max_mantissa_fast_path(pns.exponent) && !pns.too_many_digits) {
|
||||||
|
value = T(pns.mantissa);
|
||||||
|
value = value * binary_format<T>::exact_power_of_ten(pns.exponent);
|
||||||
|
if (pns.negative) { value = -value; }
|
||||||
|
return answer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
|
adjusted_mantissa am = compute_float<binary_format<T>>(pns.exponent, pns.mantissa);
|
||||||
if(pns.too_many_digits && am.power2 >= 0) {
|
if(pns.too_many_digits && am.power2 >= 0) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user