mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-07 01:06:48 +08:00
reduce register pressure.
This commit is contained in:
parent
8212e9e919
commit
b261492ae7
@ -40,7 +40,7 @@ constexpr static uint64_t powers_of_ten_uint64[] = {1UL,
|
|||||||
// to slow down performance for faster algorithms, and this is still fast.
|
// to slow down performance for faster algorithms, and this is still fast.
|
||||||
template <typename UC>
|
template <typename UC>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int16_t
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int16_t
|
||||||
scientific_exponent(const parsed_number_string_t<UC> &num) noexcept {
|
scientific_exponent(parsed_number_string_t<UC> const &num) noexcept {
|
||||||
uint64_t mantissa = num.mantissa;
|
uint64_t mantissa = num.mantissa;
|
||||||
int16_t exponent = num.exponent;
|
int16_t exponent = num.exponent;
|
||||||
while (mantissa >= 10000) {
|
while (mantissa >= 10000) {
|
||||||
@ -61,7 +61,7 @@ scientific_exponent(const parsed_number_string_t<UC> &num) noexcept {
|
|||||||
// this converts a native floating-point number to an extended-precision float.
|
// this converts a native floating-point number to an extended-precision float.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||||
to_extended(T value) noexcept {
|
to_extended(T const &value) noexcept {
|
||||||
using equiv_uint = equiv_uint_t<T>;
|
using equiv_uint = equiv_uint_t<T>;
|
||||||
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
|
constexpr equiv_uint exponent_mask = binary_format<T>::exponent_mask();
|
||||||
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
|
constexpr equiv_uint mantissa_mask = binary_format<T>::mantissa_mask();
|
||||||
@ -96,7 +96,7 @@ to_extended(T value) noexcept {
|
|||||||
// halfway between b and b+u.
|
// halfway between b and b+u.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
||||||
to_extended_halfway(T value) noexcept {
|
to_extended_halfway(T const &value) noexcept {
|
||||||
adjusted_mantissa am = to_extended(value);
|
adjusted_mantissa am = to_extended(value);
|
||||||
am.mantissa <<= 1;
|
am.mantissa <<= 1;
|
||||||
am.mantissa += 1;
|
am.mantissa += 1;
|
||||||
@ -341,17 +341,17 @@ parse_mantissa(bigint &result, const parsed_number_string_t<UC> &num,
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
inline FASTFLOAT_CONSTEXPR20 void
|
||||||
positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept {
|
positive_digit_comp(bigint &bigmant, adjusted_mantissa &am,
|
||||||
|
int32_t const exponent) noexcept {
|
||||||
FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent)));
|
FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent)));
|
||||||
adjusted_mantissa answer;
|
|
||||||
bool truncated;
|
bool truncated;
|
||||||
answer.mantissa = bigmant.hi64(truncated);
|
am.mantissa = bigmant.hi64(truncated);
|
||||||
int bias = binary_format<T>::mantissa_explicit_bits() -
|
int32_t bias = binary_format<T>::mantissa_explicit_bits() -
|
||||||
binary_format<T>::minimum_exponent();
|
binary_format<T>::minimum_exponent();
|
||||||
answer.power2 = bigmant.bit_length() - 64 + bias;
|
am.power2 = bigmant.bit_length() - 64 + bias;
|
||||||
|
|
||||||
round<T>(answer, [truncated](adjusted_mantissa &a, int32_t shift) {
|
round<T>(am, [truncated](adjusted_mantissa &a, int32_t shift) {
|
||||||
round_nearest_tie_even(
|
round_nearest_tie_even(
|
||||||
a, shift,
|
a, shift,
|
||||||
[truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
|
[truncated](bool is_odd, bool is_halfway, bool is_above) -> bool {
|
||||||
@ -359,8 +359,6 @@ positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept {
|
|||||||
(is_odd && is_halfway);
|
(is_odd && is_halfway);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return answer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// the scaling here is quite simple: we have, for the real digits `m * 10^e`,
|
// the scaling here is quite simple: we have, for the real digits `m * 10^e`,
|
||||||
@ -369,24 +367,26 @@ positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept {
|
|||||||
// we then need to scale by `2^(f- e)`, and then the two significant digits
|
// we then need to scale by `2^(f- e)`, and then the two significant digits
|
||||||
// are of the same magnitude.
|
// are of the same magnitude.
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa
|
inline FASTFLOAT_CONSTEXPR20 void
|
||||||
negative_digit_comp(bigint &bigmant, const adjusted_mantissa am,
|
negative_digit_comp(bigint &bigmant, adjusted_mantissa &am,
|
||||||
const int32_t exponent) noexcept {
|
int32_t const exponent) noexcept {
|
||||||
bigint &real_digits = bigmant;
|
bigint &real_digits = bigmant;
|
||||||
const int32_t &real_exp = exponent;
|
const int32_t &real_exp = exponent;
|
||||||
|
|
||||||
|
T b;
|
||||||
|
{
|
||||||
// get the value of `b`, rounded down, and get a bigint representation of b+h
|
// get the value of `b`, rounded down, and get a bigint representation of b+h
|
||||||
adjusted_mantissa am_b = am;
|
adjusted_mantissa am_b = am;
|
||||||
// gcc7 buf: use a lambda to remove the noexcept qualifier bug with
|
// gcc7 bug: use a lambda to remove the noexcept qualifier bug with
|
||||||
// -Wnoexcept-type.
|
// -Wnoexcept-type.
|
||||||
round<T>(am_b,
|
round<T>(am_b,
|
||||||
[](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); });
|
[](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); });
|
||||||
T b;
|
|
||||||
to_float(
|
to_float(
|
||||||
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
||||||
false,
|
false,
|
||||||
#endif
|
#endif
|
||||||
am_b, b);
|
am_b, b);
|
||||||
|
}
|
||||||
adjusted_mantissa theor = to_extended_halfway(b);
|
adjusted_mantissa theor = to_extended_halfway(b);
|
||||||
bigint theor_digits(theor.mantissa);
|
bigint theor_digits(theor.mantissa);
|
||||||
int32_t theor_exp = theor.power2;
|
int32_t theor_exp = theor.power2;
|
||||||
@ -405,8 +405,7 @@ negative_digit_comp(bigint &bigmant, const adjusted_mantissa am,
|
|||||||
|
|
||||||
// compare digits, and use it to director rounding
|
// compare digits, and use it to director rounding
|
||||||
int ord = real_digits.compare(theor_digits);
|
int ord = real_digits.compare(theor_digits);
|
||||||
adjusted_mantissa answer = am;
|
round<T>(am, [ord](adjusted_mantissa &a, int32_t shift) {
|
||||||
round<T>(answer, [ord](adjusted_mantissa &a, int32_t shift) {
|
|
||||||
round_nearest_tie_even(
|
round_nearest_tie_even(
|
||||||
a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
|
a, shift, [ord](bool is_odd, bool _, bool __) -> bool {
|
||||||
(void)_; // not needed, since we've done our comparison
|
(void)_; // not needed, since we've done our comparison
|
||||||
@ -420,8 +419,6 @@ negative_digit_comp(bigint &bigmant, const adjusted_mantissa am,
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return answer;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// parse the significant digits as a big integer to unambiguously round the
|
// parse the significant digits as a big integer to unambiguously round the
|
||||||
@ -438,8 +435,8 @@ negative_digit_comp(bigint &bigmant, const adjusted_mantissa am,
|
|||||||
// the actual digits. we then compare the big integer representations
|
// the actual digits. we then compare the big integer representations
|
||||||
// of both, and use that to direct rounding.
|
// of both, and use that to direct rounding.
|
||||||
template <typename T, typename UC>
|
template <typename T, typename UC>
|
||||||
inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa digit_comp(
|
inline FASTFLOAT_CONSTEXPR20 void digit_comp(
|
||||||
const parsed_number_string_t<UC> &num, adjusted_mantissa &am) noexcept {
|
parsed_number_string_t<UC> const &num, adjusted_mantissa &am) noexcept {
|
||||||
// remove the invalid exponent bias
|
// remove the invalid exponent bias
|
||||||
am.power2 -= invalid_am_bias;
|
am.power2 -= invalid_am_bias;
|
||||||
|
|
||||||
@ -451,9 +448,9 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa digit_comp(
|
|||||||
// can't underflow, since digits is at most max_digits.
|
// can't underflow, since digits is at most max_digits.
|
||||||
int16_t exponent = sci_exp + 1 - digits;
|
int16_t exponent = sci_exp + 1 - digits;
|
||||||
if (exponent >= 0) {
|
if (exponent >= 0) {
|
||||||
return positive_digit_comp<T>(bigmant, exponent);
|
positive_digit_comp<T>(bigmant, am, exponent);
|
||||||
} else {
|
} else {
|
||||||
return negative_digit_comp<T>(bigmant, am, exponent);
|
negative_digit_comp<T>(bigmant, am, exponent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -772,7 +772,7 @@ inline constexpr int binary_format<std::float16_t>::smallest_power_of_ten() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline constexpr unsigned int binary_format<std::float16_t>::max_digits() {
|
inline constexpr size_t binary_format<std::float16_t>::max_digits() {
|
||||||
return 22;
|
return 22;
|
||||||
}
|
}
|
||||||
#endif // __STDCPP_FLOAT16_T__
|
#endif // __STDCPP_FLOAT16_T__
|
||||||
@ -899,7 +899,7 @@ inline constexpr int binary_format<std::bfloat16_t>::smallest_power_of_ten() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template <>
|
template <>
|
||||||
inline constexpr unsigned int binary_format<std::bfloat16_t>::max_digits() {
|
inline constexpr size_t binary_format<std::bfloat16_t>::max_digits() {
|
||||||
return 98;
|
return 98;
|
||||||
}
|
}
|
||||||
#endif // __STDCPP_BFLOAT16_T__
|
#endif // __STDCPP_BFLOAT16_T__
|
||||||
@ -1009,7 +1009,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float(
|
|||||||
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
||||||
bool const negative,
|
bool const negative,
|
||||||
#endif
|
#endif
|
||||||
adjusted_mantissa const am, T &value) noexcept {
|
adjusted_mantissa const &am, T &value) noexcept {
|
||||||
using equiv_uint = equiv_uint_t<T>;
|
using equiv_uint = equiv_uint_t<T>;
|
||||||
equiv_uint word = equiv_uint(am.mantissa);
|
equiv_uint word = equiv_uint(am.mantissa);
|
||||||
word = equiv_uint(word | equiv_uint(am.power2)
|
word = equiv_uint(word | equiv_uint(am.power2)
|
||||||
|
|||||||
@ -283,7 +283,7 @@ from_chars_advanced(parsed_number_string_t<UC> const &pns, T &value) noexcept {
|
|||||||
// and we have an invalid power (am.power2 < 0), then we need to go the long
|
// and we have an invalid power (am.power2 < 0), then we need to go the long
|
||||||
// way around again. This is very uncommon.
|
// way around again. This is very uncommon.
|
||||||
if (am.power2 < 0) {
|
if (am.power2 < 0) {
|
||||||
am = digit_comp<T>(pns, am);
|
digit_comp<T>(pns, am);
|
||||||
}
|
}
|
||||||
to_float(
|
to_float(
|
||||||
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
#ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user