[libc] Fix is_subnormal for Intel Extended Precision (#78592)

Also turn a set of `get_biased_exponent() == 0` into `is_subnormal()`
which is clearer.
This commit is contained in:
Guillaume Chatelet 2024-01-19 09:36:03 +01:00 committed by GitHub
parent 28d64c1237
commit 14f0c06f48
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 19 additions and 34 deletions

View File

@ -386,8 +386,11 @@ public:
bits = (value & FP_MASK);
}
LIBC_INLINE constexpr bool is_zero() const {
return (bits & EXP_SIG_MASK) == 0;
LIBC_INLINE constexpr bool is_zero() const { return exp_sig_bits() == 0; }
LIBC_INLINE
constexpr bool is_subnormal() const {
return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
}
LIBC_INLINE constexpr bool is_neg() const { return sign().is_neg(); }
@ -435,19 +438,11 @@ public:
return exp_sig_bits() ==
encode(BiasedExponent::BITS_ALL_ONES(), Significand::ZERO());
}
LIBC_INLINE constexpr bool is_zero() const {
return exp_sig_bits() ==
encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
LIBC_INLINE constexpr bool is_finite() const {
return exp_bits() != encode(BiasedExponent::BITS_ALL_ONES());
}
LIBC_INLINE
constexpr bool is_subnormal() const {
return exp_bits() == encode(BiasedExponent::BITS_ALL_ZEROES());
}
LIBC_INLINE constexpr bool is_normal() const {
return is_finite() && !is_subnormal();
return is_finite() && !UP::is_subnormal();
}
LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) {
@ -488,7 +483,7 @@ public:
// The function return mantissa with the implicit bit set iff the current
// value is a valid normal number.
LIBC_INLINE constexpr StorageType get_explicit_mantissa() {
if (is_subnormal())
if (UP::is_subnormal())
return sig_bits();
return (StorageType(1) << UP::SIG_LEN) | sig_bits();
}
@ -550,18 +545,9 @@ public:
return exp_sig_bits() ==
encode(BiasedExponent::BITS_ALL_ONES(), Significand::MSB());
}
LIBC_INLINE constexpr bool is_zero() const {
return exp_sig_bits() ==
encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
LIBC_INLINE constexpr bool is_finite() const {
return !is_inf() && !is_nan();
}
LIBC_INLINE
constexpr bool is_subnormal() const {
return exp_sig_bits() >
encode(BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO());
}
LIBC_INLINE constexpr bool is_normal() const {
const auto exp = exp_bits();
if (exp == encode(BiasedExponent::BITS_ALL_ZEROES()) ||

View File

@ -153,7 +153,7 @@ private:
}
// Normalize subnormal numbers.
if (bits.get_biased_exponent() == 0) {
if (bits.is_subnormal()) {
unsigned shift = evaluate_normalization_shift(bits.get_mantissa());
mantissa = StorageType(bits.get_mantissa()) << shift;
exponent = 1 - FPBits<T>::EXP_BIAS - shift;
@ -186,7 +186,7 @@ NormalFloat<long double>::init_from_bits(FPBits<long double> bits) {
return;
}
if (bits.get_biased_exponent() == 0) {
if (bits.is_subnormal()) {
if (bits.get_implicit_bit() == 0) {
// Since we ignore zero value, the mantissa in this case is non-zero.
int normalization_shift =

View File

@ -104,15 +104,15 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
int z_exp = 0;
// Normalize denormal inputs.
if (LIBC_UNLIKELY(FPBits(x).get_biased_exponent() == 0)) {
if (LIBC_UNLIKELY(FPBits(x).is_subnormal())) {
x_exp -= 52;
x *= 0x1.0p+52;
}
if (LIBC_UNLIKELY(FPBits(y).get_biased_exponent() == 0)) {
if (LIBC_UNLIKELY(FPBits(y).is_subnormal())) {
y_exp -= 52;
y *= 0x1.0p+52;
}
if (LIBC_UNLIKELY(FPBits(z).get_biased_exponent() == 0)) {
if (LIBC_UNLIKELY(FPBits(z).is_subnormal())) {
z_exp -= 52;
z *= 0x1.0p+52;
}

View File

@ -97,7 +97,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<T>, T> sqrt(T x) {
StorageType x_mant = bits.get_mantissa();
// Step 1a: Normalize denormal input and append hidden bit to the mantissa
if (bits.get_biased_exponent() == 0) {
if (bits.is_subnormal()) {
++x_exp; // let x_exp be the correct exponent of ONE bit.
internal::normalize<T>(x_exp, x_mant);
} else {

View File

@ -65,7 +65,7 @@ LIBC_INLINE long double sqrt(long double x) {
// Step 1a: Normalize denormal input
if (bits.get_implicit_bit()) {
x_mant |= ONE;
} else if (bits.get_biased_exponent() == 0) {
} else if (bits.is_subnormal()) {
normalize(x_exp, x_mant);
}

View File

@ -38,8 +38,7 @@ LIBC_INLINE long double nextafter(long double from, long double to) {
return to;
// Convert pseudo subnormal number to normal number.
if (from_bits.get_implicit_bit() == 1 &&
from_bits.get_biased_exponent() == 0) {
if (from_bits.get_implicit_bit() == 1 && from_bits.is_subnormal()) {
from_bits.set_biased_exponent(1);
}

View File

@ -457,9 +457,9 @@ public:
int thisExponent = FPBits<T>(thisAsT).get_exponent();
int inputExponent = FPBits<T>(input).get_exponent();
// Adjust the exponents for denormal numbers.
if (FPBits<T>(thisAsT).get_biased_exponent() == 0)
if (FPBits<T>(thisAsT).is_subnormal())
++thisExponent;
if (FPBits<T>(input).get_biased_exponent() == 0)
if (FPBits<T>(input).is_subnormal())
++inputExponent;
if (thisAsT * input < 0 || thisExponent == inputExponent) {
@ -481,9 +481,9 @@ public:
int minExponent = FPBits<T>(min).get_exponent();
int maxExponent = FPBits<T>(max).get_exponent();
// Adjust the exponents for denormal numbers.
if (FPBits<T>(min).get_biased_exponent() == 0)
if (FPBits<T>(min).is_subnormal())
++minExponent;
if (FPBits<T>(max).get_biased_exponent() == 0)
if (FPBits<T>(max).is_subnormal())
++maxExponent;
MPFRNumber minMPFR(min);