diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h index 2ec61517b0b80..ea78809dfc7f7 100644 --- a/libc/src/__support/FPUtil/BasicOperations.h +++ b/libc/src/__support/FPUtil/BasicOperations.h @@ -20,23 +20,23 @@ namespace fputil { template , int> = 0> LIBC_INLINE T abs(T x) { FPBits bits(x); - bits.set_sign(0); + bits.set_sign(Sign::POS); return T(bits); } template , int> = 0> LIBC_INLINE T fmin(T x, T y) { - FPBits bitx(x), bity(y); + const FPBits bitx(x), bity(y); if (bitx.is_nan()) { return y; } else if (bity.is_nan()) { return x; - } else if (bitx.get_sign() != bity.get_sign()) { + } else if (bitx.sign() != bity.sign()) { // To make sure that fmin(+0, -0) == -0 == fmin(-0, +0), whenever x and // y has different signs and both are not NaNs, we return the number // with negative sign. - return (bitx.get_sign() ? x : y); + return (bitx.is_neg()) ? x : y; } else { return (x < y ? x : y); } @@ -50,11 +50,11 @@ LIBC_INLINE T fmax(T x, T y) { return y; } else if (bity.is_nan()) { return x; - } else if (bitx.get_sign() != bity.get_sign()) { + } else if (bitx.sign() != bity.sign()) { // To make sure that fmax(+0, -0) == +0 == fmax(-0, +0), whenever x and // y has different signs and both are not NaNs, we return the number // with positive sign. - return (bitx.get_sign() ? y : x); + return (bitx.is_neg() ? y : x); } else { return (x > y ? x : y); } diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h index 65bbe6b099dd0..1c09e7906165f 100644 --- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h +++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h @@ -43,13 +43,14 @@ LIBC_INLINE T remquo(T x, T y, int &q) { return x; } - bool result_sign = (xbits.get_sign() == ybits.get_sign() ? false : true); + const Sign result_sign = + (xbits.sign() == ybits.sign() ? Sign::POS : Sign::NEG); // Once we know the sign of the result, we can just operate on the absolute // values. The correct sign can be applied to the result after the result // is evaluated. - xbits.set_sign(0); - ybits.set_sign(0); + xbits.set_sign(Sign::POS); + ybits.set_sign(Sign::POS); NormalFloat normalx(xbits), normaly(ybits); int exp = normalx.exponent - normaly.exponent; @@ -72,7 +73,7 @@ LIBC_INLINE T remquo(T x, T y, int &q) { mx = n - my; if (mx == 0) { - q = result_sign ? -q : q; + q = result_sign.is_neg() ? -q : q; return LIBC_NAMESPACE::fputil::copysign(T(0.0), x); } } @@ -107,7 +108,7 @@ LIBC_INLINE T remquo(T x, T y, int &q) { native_remainder = -native_remainder; } - q = result_sign ? -q : q; + q = result_sign.is_neg() ? -q : q; if (native_remainder == T(0.0)) return LIBC_NAMESPACE::fputil::copysign(T(0.0), x); return native_remainder; diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h index 4309a535abd07..3ee6289b74964 100644 --- a/libc/src/__support/FPUtil/FPBits.h +++ b/libc/src/__support/FPUtil/FPBits.h @@ -31,6 +31,32 @@ enum class FPType { X86_Binary80, }; +// A type to interact with floating point type signs. +// This may be moved outside of 'fputil' if useful. +struct Sign { + LIBC_INLINE constexpr bool is_pos() const { return !is_negative; } + LIBC_INLINE constexpr bool is_neg() const { return is_negative; } + + LIBC_INLINE friend constexpr bool operator==(Sign a, Sign b) { + return a.is_negative == b.is_negative; + } + LIBC_INLINE friend constexpr bool operator!=(Sign a, Sign b) { + return !(a == b); + } + + static const Sign POS; + static const Sign NEG; + +private: + LIBC_INLINE constexpr explicit Sign(bool is_negative) + : is_negative(is_negative) {} + + bool is_negative; +}; + +LIBC_INLINE_VAR constexpr Sign Sign::NEG = Sign(true); +LIBC_INLINE_VAR constexpr Sign Sign::POS = Sign(false); + // The classes hierarchy is as follows: // // ┌───────────────────┐ @@ -273,9 +299,9 @@ struct FPRepBase : public internal::FPLayout { return encode(exp) | encode(sig); } - LIBC_INLINE static constexpr StorageType encode(bool sign, BiasedExponent exp, + LIBC_INLINE static constexpr StorageType encode(Sign sign, BiasedExponent exp, Significand sig) { - if (sign) + if (sign.is_neg()) return SIGN_MASK | encode(exp, sig); return encode(exp, sig); } @@ -309,12 +335,12 @@ struct FPRepBase : public internal::FPLayout { StorageType bits = 0; public: - LIBC_INLINE constexpr bool get_sign() const { - return (bits & SIGN_MASK) != 0; + LIBC_INLINE constexpr Sign sign() const { + return (bits & SIGN_MASK) ? Sign::NEG : Sign::POS; } - LIBC_INLINE constexpr void set_sign(bool signVal) { - if (get_sign() != signVal) + LIBC_INLINE constexpr void set_sign(Sign signVal) { + if (sign() != signVal) bits ^= SIGN_MASK; } @@ -363,6 +389,9 @@ struct FPRepBase : public internal::FPLayout { LIBC_INLINE constexpr bool is_zero() const { return (bits & EXP_SIG_MASK) == 0; } + + LIBC_INLINE constexpr bool is_neg() const { return sign().is_neg(); } + LIBC_INLINE constexpr bool is_pos() const { return sign().is_pos(); } }; namespace internal { @@ -421,35 +450,37 @@ template struct FPRep : public FPRepBase { return is_finite() && !is_subnormal(); } - LIBC_INLINE static constexpr StorageType zero(bool sign = false) { + LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO()); } - LIBC_INLINE static constexpr StorageType one(bool sign = false) { + LIBC_INLINE static constexpr StorageType one(Sign sign = Sign::POS) { return encode(sign, Exponent::ZERO(), Significand::ZERO()); } - LIBC_INLINE static constexpr StorageType min_subnormal(bool sign = false) { + LIBC_INLINE static constexpr StorageType + min_subnormal(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::LSB()); } - LIBC_INLINE static constexpr StorageType max_subnormal(bool sign = false) { + LIBC_INLINE static constexpr StorageType + max_subnormal(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::BITS_ALL_ONES()); } - LIBC_INLINE static constexpr StorageType min_normal(bool sign = false) { + LIBC_INLINE static constexpr StorageType min_normal(Sign sign = Sign::POS) { return encode(sign, Exponent::MIN(), Significand::ZERO()); } - LIBC_INLINE static constexpr StorageType max_normal(bool sign = false) { + LIBC_INLINE static constexpr StorageType max_normal(Sign sign = Sign::POS) { return encode(sign, Exponent::MAX(), Significand::BITS_ALL_ONES()); } - LIBC_INLINE static constexpr StorageType inf(bool sign = false) { + LIBC_INLINE static constexpr StorageType inf(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::ZERO()); } - LIBC_INLINE static constexpr StorageType build_nan(bool sign = false, + LIBC_INLINE static constexpr StorageType build_nan(Sign sign = Sign::POS, StorageType v = 0) { return encode(sign, BiasedExponent::BITS_ALL_ONES(), (v ? Significand(v) : (Significand::MSB() >> 1))); } - LIBC_INLINE static constexpr StorageType build_quiet_nan(bool sign = false, - StorageType v = 0) { + LIBC_INLINE static constexpr StorageType + build_quiet_nan(Sign sign = Sign::POS, StorageType v = 0) { return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::MSB() | Significand(v)); } @@ -539,36 +570,38 @@ struct FPRep : public FPRepBase { return get_implicit_bit(); } - LIBC_INLINE static constexpr StorageType zero(bool sign = false) { + LIBC_INLINE static constexpr StorageType zero(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::ZERO()); } - LIBC_INLINE static constexpr StorageType one(bool sign = false) { + LIBC_INLINE static constexpr StorageType one(Sign sign = Sign::POS) { return encode(sign, Exponent::ZERO(), Significand::MSB()); } - LIBC_INLINE static constexpr StorageType min_subnormal(bool sign = false) { + LIBC_INLINE static constexpr StorageType + min_subnormal(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::LSB()); } - LIBC_INLINE static constexpr StorageType max_subnormal(bool sign = false) { + LIBC_INLINE static constexpr StorageType + max_subnormal(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ZEROES(), Significand::BITS_ALL_ONES() ^ Significand::MSB()); } - LIBC_INLINE static constexpr StorageType min_normal(bool sign = false) { + LIBC_INLINE static constexpr StorageType min_normal(Sign sign = Sign::POS) { return encode(sign, Exponent::MIN(), Significand::MSB()); } - LIBC_INLINE static constexpr StorageType max_normal(bool sign = false) { + LIBC_INLINE static constexpr StorageType max_normal(Sign sign = Sign::POS) { return encode(sign, Exponent::MAX(), Significand::BITS_ALL_ONES()); } - LIBC_INLINE static constexpr StorageType inf(bool sign = false) { + LIBC_INLINE static constexpr StorageType inf(Sign sign = Sign::POS) { return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::MSB()); } - LIBC_INLINE static constexpr StorageType build_nan(bool sign = false, + LIBC_INLINE static constexpr StorageType build_nan(Sign sign = Sign::POS, StorageType v = 0) { return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::MSB() | (v ? Significand(v) : (Significand::MSB() >> 2))); } - LIBC_INLINE static constexpr StorageType build_quiet_nan(bool sign = false, - StorageType v = 0) { + LIBC_INLINE static constexpr StorageType + build_quiet_nan(Sign sign = Sign::POS, StorageType v = 0) { return encode(sign, BiasedExponent::BITS_ALL_ONES(), Significand::MSB() | (Significand::MSB() >> 1) | Significand(v)); @@ -642,10 +675,10 @@ template struct FPBits : public internal::FPRep()> { // Constants. static constexpr int MAX_BIASED_EXPONENT = (1 << EXP_LEN) - 1; - static constexpr StorageType MIN_NORMAL = UP::min_normal(false); - static constexpr StorageType MAX_NORMAL = UP::max_normal(false); - static constexpr StorageType MIN_SUBNORMAL = UP::min_subnormal(false); - static constexpr StorageType MAX_SUBNORMAL = UP::max_subnormal(false); + static constexpr StorageType MIN_NORMAL = UP::min_normal(Sign::POS); + static constexpr StorageType MAX_NORMAL = UP::max_normal(Sign::POS); + static constexpr StorageType MIN_SUBNORMAL = UP::min_subnormal(Sign::POS); + static constexpr StorageType MAX_SUBNORMAL = UP::max_subnormal(Sign::POS); // Constructors. LIBC_INLINE constexpr FPBits() = default; @@ -675,45 +708,46 @@ template struct FPBits : public internal::FPRep()> { // Methods below this are used by tests. - LIBC_INLINE static constexpr T zero(bool sign = false) { - return FPBits(UP::zero(sign)).get_val(); + LIBC_INLINE static constexpr T one(Sign sign = Sign::POS) { + return FPBits(UP::one(sign)).get_val(); } - LIBC_INLINE static constexpr T neg_zero() { return zero(true); } + LIBC_INLINE static constexpr T zero(Sign sign = Sign::POS) { + return FPBits(UP::zero(sign)).get_val(); + } - LIBC_INLINE static constexpr T inf(bool sign = false) { + LIBC_INLINE static constexpr T inf(Sign sign = Sign::POS) { return FPBits(UP::inf(sign)).get_val(); } - LIBC_INLINE static constexpr T neg_inf() { return inf(true); } - LIBC_INLINE static constexpr T min_normal() { - return FPBits(UP::min_normal(false)).get_val(); + return FPBits(UP::min_normal(Sign::POS)).get_val(); } LIBC_INLINE static constexpr T max_normal() { - return FPBits(UP::max_normal(false)).get_val(); + return FPBits(UP::max_normal(Sign::POS)).get_val(); } LIBC_INLINE static constexpr T min_denormal() { - return FPBits(UP::min_subnormal(false)).get_val(); + return FPBits(UP::min_subnormal(Sign::POS)).get_val(); } LIBC_INLINE static constexpr T max_denormal() { - return FPBits(UP::max_subnormal(false)).get_val(); + return FPBits(UP::max_subnormal(Sign::POS)).get_val(); } LIBC_INLINE static constexpr T build_nan(StorageType v) { - return FPBits(UP::build_nan(false, v)).get_val(); + return FPBits(UP::build_nan(Sign::POS, v)).get_val(); } - LIBC_INLINE static constexpr T build_quiet_nan(StorageType v) { - return FPBits(UP::build_quiet_nan(false, v)).get_val(); + LIBC_INLINE static constexpr T build_quiet_nan(StorageType v, + Sign sign = Sign::POS) { + return FPBits(UP::build_quiet_nan(sign, v)).get_val(); } // TODO: Use an uint32_t for 'biased_exp'. LIBC_INLINE static constexpr FPBits - create_value(bool sign, StorageType biased_exp, StorageType mantissa) { + create_value(Sign sign, StorageType biased_exp, StorageType mantissa) { static_assert(get_fp_type() != FPType::X86_Binary80, "This function is not tested for X86 Extended Precision"); return FPBits(UP::encode( diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h index 42433b9b8442d..81c8281f3c7bb 100644 --- a/libc/src/__support/FPUtil/ManipulationFunctions.h +++ b/libc/src/__support/FPUtil/ManipulationFunctions.h @@ -49,13 +49,13 @@ LIBC_INLINE T modf(T x, T &iptr) { return x; } else if (bits.is_inf()) { iptr = x; - return bits.get_sign() ? T(FPBits::neg_zero()) : T(FPBits::zero()); + return T(FPBits::zero(bits.sign())); } else { iptr = trunc(x); if (x == iptr) { // If x is already an integer value, then return zero with the right // sign. - return bits.get_sign() ? T(FPBits::neg_zero()) : T(FPBits::zero()); + return T(FPBits::zero(bits.sign())); } else { return x - iptr; } @@ -65,7 +65,7 @@ LIBC_INLINE T modf(T x, T &iptr) { template , int> = 0> LIBC_INLINE T copysign(T x, T y) { FPBits xbits(x); - xbits.set_sign(FPBits(y).get_sign()); + xbits.set_sign(FPBits(y).sign()); return T(xbits); } @@ -103,12 +103,12 @@ LIBC_INLINE T logb(T x) { if (bits.is_zero()) { // TODO(Floating point exception): Raise div-by-zero exception. // TODO(errno): POSIX requires setting errno to ERANGE. - return T(FPBits::neg_inf()); + return T(FPBits::inf(Sign::NEG)); } else if (bits.is_nan()) { return x; } else if (bits.is_inf()) { // Return positive infinity. - return T(FPBits::inf()); + return T(FPBits::inf(Sign::POS)); } NormalFloat normal(bits); @@ -131,11 +131,11 @@ LIBC_INLINE T ldexp(T x, int exp) { // calculating the limit. int exp_limit = FPBits::MAX_BIASED_EXPONENT + FPBits::FRACTION_LEN + 1; if (exp > exp_limit) - return bits.get_sign() ? T(FPBits::neg_inf()) : T(FPBits::inf()); + return T(FPBits::inf(bits.sign())); // Similarly on the negative side we return zero early if |exp| is too small. if (exp < -exp_limit) - return bits.get_sign() ? T(FPBits::neg_zero()) : T(FPBits::zero()); + return T(FPBits::zero(bits.sign())); // For all other values, NormalFloat to T conversion handles it the right way. NormalFloat normal(bits); @@ -173,7 +173,7 @@ LIBC_INLINE T nextafter(T from, U to) { } } else { int_val = FPBits::MIN_SUBNORMAL; - if (to_bits.get_sign()) + if (to_bits.is_neg()) int_val |= FPBits::SIGN_MASK; } diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h index 64c44e0b3a0c4..62568977dc0c8 100644 --- a/libc/src/__support/FPUtil/NearestIntegerOperations.h +++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h @@ -40,12 +40,8 @@ LIBC_INLINE T trunc(T x) { return x; // If the exponent is such that abs(x) is less than 1, then return 0. - if (exponent <= -1) { - if (bits.get_sign()) - return T(-0.0); - else - return T(0.0); - } + if (exponent <= -1) + return T(FPBits::zero(bits.sign())); int trim_size = FPBits::FRACTION_LEN - exponent; bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size); @@ -60,7 +56,7 @@ LIBC_INLINE T ceil(T x) { if (bits.is_inf_or_nan() || bits.is_zero()) return x; - bool is_neg = bits.get_sign(); + bool is_neg = bits.is_neg(); int exponent = bits.get_exponent(); // If the exponent is greater than the most negative mantissa @@ -93,7 +89,7 @@ LIBC_INLINE T ceil(T x) { template , int> = 0> LIBC_INLINE T floor(T x) { FPBits bits(x); - if (bits.get_sign()) { + if (bits.is_neg()) { return -ceil(-x); } else { return trunc(x); @@ -109,7 +105,6 @@ LIBC_INLINE T round(T x) { if (bits.is_inf_or_nan() || bits.is_zero()) return x; - bool is_neg = bits.get_sign(); int exponent = bits.get_exponent(); // If the exponent is greater than the most negative mantissa @@ -119,18 +114,12 @@ LIBC_INLINE T round(T x) { if (exponent == -1) { // Absolute value of x is greater than equal to 0.5 but less than 1. - if (is_neg) - return T(-1.0); - else - return T(1.0); + return T(FPBits::one(bits.sign())); } if (exponent <= -2) { // Absolute value of x is less than 0.5. - if (is_neg) - return T(-0.0); - else - return T(0.0); + return T(FPBits::zero(bits.sign())); } uint32_t trim_size = FPBits::FRACTION_LEN - exponent; @@ -148,7 +137,7 @@ LIBC_INLINE T round(T x) { // same as the trunc value. return trunc_value; } else { - return is_neg ? trunc_value - T(1.0) : trunc_value + T(1.0); + return bits.is_neg() ? trunc_value - T(1.0) : trunc_value + T(1.0); } } @@ -161,7 +150,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) { if (bits.is_inf_or_nan() || bits.is_zero()) return x; - bool is_neg = bits.get_sign(); + bool is_neg = bits.is_neg(); int exponent = bits.get_exponent(); int rounding_mode = quick_get_round(); @@ -247,18 +236,18 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) { if (bits.is_inf_or_nan()) { set_domain_error_and_raise_invalid(); - return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX; + return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX; } int exponent = bits.get_exponent(); constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1; if (exponent > EXPONENT_LIMIT) { set_domain_error_and_raise_invalid(); - return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX; + return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX; } else if (exponent == EXPONENT_LIMIT) { - if (bits.get_sign() == 0 || bits.get_mantissa() != 0) { + if (bits.is_pos() || bits.get_mantissa() != 0) { set_domain_error_and_raise_invalid(); - return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX; + return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX; } // If the control reaches here, then it means that the rounded // value is the most negative number for the signed integer type I. diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h index e70c89a7dbe15..8b1612e1b47c6 100644 --- a/libc/src/__support/FPUtil/NormalFloat.h +++ b/libc/src/__support/FPUtil/NormalFloat.h @@ -44,10 +44,10 @@ template struct NormalFloat { static_assert(sizeof(StorageType) * 8 >= FPBits::FRACTION_LEN + 1, "Bad type for mantissa in NormalFloat."); - bool sign; + Sign sign = Sign::POS; LIBC_INLINE NormalFloat(int32_t e, StorageType m, bool s) - : exponent(e), mantissa(m), sign(s) { + : exponent(e), mantissa(m), sign(s ? Sign::NEG : Sign::POS) { if (mantissa >= ONE) return; @@ -64,20 +64,21 @@ template struct NormalFloat { // Returns -1 is this number is less than |other|, 0 if this number is equal // to |other|, and 1 if this number is greater than |other|. LIBC_INLINE int cmp(const NormalFloat &other) const { + const int result = sign.is_neg() ? -1 : 1; if (sign != other.sign) - return sign ? -1 : 1; + return result; if (exponent > other.exponent) { - return sign ? -1 : 1; + return result; } else if (exponent == other.exponent) { if (mantissa > other.mantissa) - return sign ? -1 : 1; + return result; else if (mantissa == other.mantissa) return 0; else - return sign ? 1 : -1; + return -result; } else { - return sign ? 1 : -1; + return -result; } } @@ -95,7 +96,7 @@ template struct NormalFloat { // Max exponent is of the form 0xFF...E. That is why -2 and not -1. constexpr int MAX_EXPONENT_VALUE = (1 << FPBits::EXP_LEN) - 2; if (biased_exponent > MAX_EXPONENT_VALUE) { - return sign ? T(FPBits::neg_inf()) : T(FPBits::inf()); + return T(FPBits::inf(sign)); } FPBits result(T(0.0)); @@ -141,7 +142,7 @@ template struct NormalFloat { private: LIBC_INLINE void init_from_bits(FPBits bits) { - sign = bits.get_sign(); + sign = bits.sign(); if (bits.is_inf_or_nan() || bits.is_zero()) { // Ignore special bit patterns. Implementations deal with them separately @@ -175,7 +176,7 @@ template struct NormalFloat { template <> LIBC_INLINE void NormalFloat::init_from_bits(FPBits bits) { - sign = bits.get_sign(); + sign = bits.sign(); if (bits.is_inf_or_nan() || bits.is_zero()) { // Ignore special bit patterns. Implementations deal with them separately @@ -214,7 +215,7 @@ template <> LIBC_INLINE NormalFloat::operator long double() const { // Max exponent is of the form 0xFF...E. That is why -2 and not -1. constexpr int MAX_EXPONENT_VALUE = (1 << LDBits::EXP_LEN) - 2; if (biased_exponent > MAX_EXPONENT_VALUE) { - return sign ? LDBits::neg_inf() : LDBits::inf(); + return LDBits::inf(sign); } FPBits result(0.0l); diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h index ccd3c69bf3db2..439741d2c497c 100644 --- a/libc/src/__support/FPUtil/dyadic_float.h +++ b/libc/src/__support/FPUtil/dyadic_float.h @@ -33,7 +33,7 @@ namespace LIBC_NAMESPACE::fputil { template struct DyadicFloat { using MantissaType = LIBC_NAMESPACE::cpp::UInt; - bool sign = false; + Sign sign = Sign::POS; int exponent = 0; MantissaType mantissa = MantissaType(0); @@ -43,14 +43,14 @@ template struct DyadicFloat { DyadicFloat(T x) { static_assert(FPBits::FRACTION_LEN < Bits); FPBits x_bits(x); - sign = x_bits.get_sign(); + sign = x_bits.sign(); exponent = x_bits.get_exponent() - FPBits::FRACTION_LEN; mantissa = MantissaType(x_bits.get_explicit_mantissa()); normalize(); } constexpr DyadicFloat(bool s, int e, MantissaType m) - : sign(s), exponent(e), mantissa(m) { + : sign(s ? Sign::NEG : Sign::POS), exponent(e), mantissa(m) { normalize(); } @@ -172,7 +172,7 @@ template struct DyadicFloat { new_mant >>= (-exponent); } - if (sign) { + if (sign.is_neg()) { new_mant = (~new_mant) + 1; } @@ -251,7 +251,7 @@ template constexpr DyadicFloat quick_mul(DyadicFloat a, DyadicFloat b) { DyadicFloat result; - result.sign = (a.sign != b.sign); + result.sign = (a.sign != b.sign) ? Sign::NEG : Sign::POS; result.exponent = a.exponent + b.exponent + int(Bits); if (!(a.mantissa.is_zero() || b.mantissa.is_zero())) { diff --git a/libc/src/__support/FPUtil/fpbits_str.h b/libc/src/__support/FPUtil/fpbits_str.h index 50019f32b2c44..a1654cddad746 100644 --- a/libc/src/__support/FPUtil/fpbits_str.h +++ b/libc/src/__support/FPUtil/fpbits_str.h @@ -35,13 +35,16 @@ using ZeroPaddedHexFmt = IntegerToString< // floating encoding. template LIBC_INLINE cpp::string str(fputil::FPBits x) { using StorageType = typename fputil::FPBits::StorageType; + using Sign = fputil::Sign; if (x.is_nan()) return "(NaN)"; if (x.is_inf()) - return x.get_sign() ? "(-Infinity)" : "(+Infinity)"; + return x.is_neg() ? "(-Infinity)" : "(+Infinity)"; - const auto sign_char = [](bool sign) -> char { return sign ? '1' : '0'; }; + const auto sign_char = [](Sign sign) -> char { + return sign.is_neg() ? '1' : '0'; + }; cpp::string s; @@ -49,7 +52,7 @@ template LIBC_INLINE cpp::string str(fputil::FPBits x) { s += bits.view(); s += " = (S: "; - s += sign_char(x.get_sign()); + s += sign_char(x.sign()); s += ", E: "; const details::ZeroPaddedHexFmt exponent(x.get_biased_exponent()); @@ -57,7 +60,7 @@ template LIBC_INLINE cpp::string str(fputil::FPBits x) { if constexpr (fputil::get_fp_type() == fputil::FPType::X86_Binary80) { s += ", I: "; - s += sign_char(x.get_implicit_bit()); + s += sign_char(x.get_implicit_bit() ? Sign::NEG : Sign::POS); } s += ", M: "; diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h index b88089ee679f2..9c67c645d5243 100644 --- a/libc/src/__support/FPUtil/generic/FMA.h +++ b/libc/src/__support/FPUtil/generic/FMA.h @@ -64,7 +64,7 @@ template <> LIBC_INLINE float fma(float x, float y, float z) { // Update sticky bits if t != 0.0 and the least (52 - 23 - 1 = 28) bits are // zero. if (!t.is_zero() && ((bit_sum.get_mantissa() & 0xfff'ffffULL) == 0)) { - if (bit_sum.get_sign() != t.get_sign()) { + if (bit_sum.sign() != t.sign()) { bit_sum.set_mantissa(bit_sum.get_mantissa() + 1); } else if (bit_sum.get_mantissa()) { bit_sum.set_mantissa(bit_sum.get_mantissa() - 1); @@ -118,10 +118,8 @@ template <> LIBC_INLINE double fma(double x, double y, double z) { } FPBits x_bits(x), y_bits(y), z_bits(z); - bool x_sign = x_bits.get_sign(); - bool y_sign = y_bits.get_sign(); - bool z_sign = z_bits.get_sign(); - bool prod_sign = x_sign != y_sign; + const Sign z_sign = z_bits.sign(); + Sign prod_sign = (x_bits.sign() == y_bits.sign()) ? Sign::POS : Sign::NEG; x_exp += x_bits.get_biased_exponent(); y_exp += y_bits.get_biased_exponent(); z_exp += z_bits.get_biased_exponent(); @@ -248,27 +246,26 @@ template <> LIBC_INLINE double fma(double x, double y, double z) { } } else { // Return +0.0 when there is exact cancellation, i.e., x*y == -z exactly. - prod_sign = false; + prod_sign = Sign::POS; } // Finalize the result. int round_mode = fputil::quick_get_round(); if (LIBC_UNLIKELY(r_exp >= FPBits::MAX_BIASED_EXPONENT)) { if ((round_mode == FE_TOWARDZERO) || - (round_mode == FE_UPWARD && prod_sign) || - (round_mode == FE_DOWNWARD && !prod_sign)) { + (round_mode == FE_UPWARD && prod_sign.is_neg()) || + (round_mode == FE_DOWNWARD && prod_sign.is_pos())) { result = FPBits::MAX_NORMAL; - return prod_sign ? -cpp::bit_cast(result) - : cpp::bit_cast(result); + return prod_sign.is_neg() ? -cpp::bit_cast(result) + : cpp::bit_cast(result); } - return prod_sign ? static_cast(FPBits::neg_inf()) - : static_cast(FPBits::inf()); + return static_cast(FPBits::inf(prod_sign)); } // Remove hidden bit and append the exponent field and sign bit. result = (result & FPBits::FRACTION_MASK) | (static_cast(r_exp) << FPBits::FRACTION_LEN); - if (prod_sign) { + if (prod_sign.is_neg()) { result |= FPBits::SIGN_MASK; } @@ -276,8 +273,8 @@ template <> LIBC_INLINE double fma(double x, double y, double z) { if (round_mode == FE_TONEAREST) { if (round_bit && (sticky_bits || ((result & 1) != 0))) ++result; - } else if ((round_mode == FE_UPWARD && !prod_sign) || - (round_mode == FE_DOWNWARD && prod_sign)) { + } else if ((round_mode == FE_UPWARD && prod_sign.is_pos()) || + (round_mode == FE_DOWNWARD && prod_sign.is_neg())) { if (round_bit || sticky_bits) ++result; } diff --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h index d12be7bb14d07..f4000b97751ef 100644 --- a/libc/src/__support/FPUtil/generic/FMod.h +++ b/libc/src/__support/FPUtil/generic/FMod.h @@ -308,9 +308,9 @@ class FMod { if (T out; Wrapper::pre_check(x, y, out)) return out; FPB sx(x), sy(y); - bool sign = sx.get_sign(); - sx.set_sign(false); - sy.set_sign(false); + Sign sign = sx.sign(); + sx.set_sign(Sign::POS); + sy.set_sign(Sign::POS); FPB result = eval_internal(sx, sy); result.set_sign(sign); return result.get_val(); diff --git a/libc/src/__support/FPUtil/generic/sqrt.h b/libc/src/__support/FPUtil/generic/sqrt.h index 7d56462a16856..f273b678edf52 100644 --- a/libc/src/__support/FPUtil/generic/sqrt.h +++ b/libc/src/__support/FPUtil/generic/sqrt.h @@ -77,7 +77,7 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { FPBits bits(x); if (bits.is_inf_or_nan()) { - if (bits.get_sign() && (bits.get_mantissa() == 0)) { + if (bits.is_neg() && (bits.get_mantissa() == 0)) { // sqrt(-Inf) = NaN return FPBits::build_quiet_nan(ONE >> 1); } else { @@ -89,7 +89,7 @@ LIBC_INLINE cpp::enable_if_t, T> sqrt(T x) { // sqrt(+0) = +0 // sqrt(-0) = -0 return x; - } else if (bits.get_sign()) { + } else if (bits.is_neg()) { // sqrt( negative numbers ) = NaN return FPBits::build_quiet_nan(ONE >> 1); } else { diff --git a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h index 8815a18cfbc39..4fe9b49ff41cf 100644 --- a/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h +++ b/libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h @@ -43,7 +43,7 @@ LIBC_INLINE long double sqrt(long double x) { FPBits bits(x); if (bits.is_inf_or_nan()) { - if (bits.get_sign() && (bits.get_mantissa() == 0)) { + if (bits.is_neg() && (bits.get_mantissa() == 0)) { // sqrt(-Inf) = NaN return LDBits::build_quiet_nan(ONE >> 1); } else { @@ -55,7 +55,7 @@ LIBC_INLINE long double sqrt(long double x) { // sqrt(+0) = +0 // sqrt(-0) = -0 return x; - } else if (bits.get_sign()) { + } else if (bits.is_neg()) { // sqrt( negative numbers ) = NaN return LDBits::build_quiet_nan(ONE >> 1); } else { diff --git a/libc/src/__support/float_to_string.h b/libc/src/__support/float_to_string.h index 52442608798a5..ab1afbe54dfac 100644 --- a/libc/src/__support/float_to_string.h +++ b/libc/src/__support/float_to_string.h @@ -412,7 +412,6 @@ LIBC_INLINE uint32_t mul_shift_mod_1e9(const FPBits::StorageType mantissa, template , int> = 0> class FloatToString { fputil::FPBits float_bits; - bool is_negative; int exponent; FPBits::StorageType mantissa; @@ -421,14 +420,11 @@ class FloatToString { public: LIBC_INLINE constexpr FloatToString(T init_float) : float_bits(init_float) { - is_negative = float_bits.get_sign(); exponent = float_bits.get_explicit_exponent(); mantissa = float_bits.get_explicit_mantissa(); // Adjust for the width of the mantissa. exponent -= FRACTION_LEN; - - // init_convert(); } LIBC_INLINE constexpr bool is_nan() { return float_bits.is_nan(); } diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h index f2d4ec7fb11f8..dd7dfc730ea2c 100644 --- a/libc/src/__support/str_to_float.h +++ b/libc/src/__support/str_to_float.h @@ -1072,6 +1072,7 @@ template LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { using FPBits = typename fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = fputil::Sign; FPBits result = FPBits(); bool seen_digit = false; @@ -1087,7 +1088,7 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { } if (sign == '-') { - result.set_sign(true); + result.set_sign(Sign::NEG); } static constexpr char DECIMAL_POINT = '.'; @@ -1165,22 +1166,13 @@ LIBC_INLINE StrToNumResult strtofloatingpoint(const char *__restrict src) { index = left_paren; } } - - if (result.get_sign()) { - result = FPBits(result.build_quiet_nan(nan_mantissa)); - result.set_sign(true); - } else { - result = FPBits(result.build_quiet_nan(nan_mantissa)); - } + result = FPBits(result.build_quiet_nan(nan_mantissa, result.sign())); } } else if (tolower(src[index]) == 'i') { // INF if (tolower(src[index + 1]) == inf_string[1] && tolower(src[index + 2]) == inf_string[2]) { seen_digit = true; - if (result.get_sign()) - result = FPBits(result.neg_inf()); - else - result = FPBits(result.inf()); + result = FPBits(result.inf(result.sign())); if (tolower(src[index + 3]) == inf_string[3] && tolower(src[index + 4]) == inf_string[4] && tolower(src[index + 5]) == inf_string[5] && diff --git a/libc/src/math/generic/acosf.cpp b/libc/src/math/generic/acosf.cpp index 2a9b2a6852fe9..67832596a67fb 100644 --- a/libc/src/math/generic/acosf.cpp +++ b/libc/src/math/generic/acosf.cpp @@ -38,6 +38,7 @@ static constexpr fputil::ExceptValues ACOSF_EXCEPTS = {{ LLVM_LIBC_FUNCTION(float, acosf, (float x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; FPBits xbits(x); uint32_t x_uint = xbits.uintval(); uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU; @@ -109,7 +110,7 @@ LLVM_LIBC_FUNCTION(float, acosf, (float x)) { // acos(x) = pi - acos(-x) // which is reduced to the postive case. - xbits.set_sign(false); + xbits.set_sign(Sign::POS); double xd = static_cast(xbits.get_val()); double u = fputil::multiply_add(-0.5, xd, 0.5); double cv = 2 * fputil::sqrt(u); diff --git a/libc/src/math/generic/asinf.cpp b/libc/src/math/generic/asinf.cpp index 51eefe984b677..bc0d27c1eebc5 100644 --- a/libc/src/math/generic/asinf.cpp +++ b/libc/src/math/generic/asinf.cpp @@ -44,6 +44,7 @@ static constexpr fputil::ExceptValues ASINF_EXCEPTS_HI = {{ LLVM_LIBC_FUNCTION(float, asinf, (float x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; FPBits xbits(x); uint32_t x_uint = xbits.uintval(); uint32_t x_abs = xbits.uintval() & 0x7fff'ffffU; @@ -139,7 +140,7 @@ LLVM_LIBC_FUNCTION(float, asinf, (float x)) { // |x| <= 0.5: // asin(x) ~ pi/2 - 2 * sqrt(u) * P(u), - xbits.set_sign(false); + xbits.set_sign(Sign::POS); double sign = SIGN[x_sign]; double xd = static_cast(xbits.get_val()); double u = fputil::multiply_add(-0.5, xd, 0.5); diff --git a/libc/src/math/generic/atanf.cpp b/libc/src/math/generic/atanf.cpp index f2e4f8bb93b6f..e0f8a1bfc2ecc 100644 --- a/libc/src/math/generic/atanf.cpp +++ b/libc/src/math/generic/atanf.cpp @@ -17,18 +17,20 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, atanf, (float x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; // x == 0.0 if (LIBC_UNLIKELY(x == 0.0f)) return x; FPBits xbits(x); - bool sign = xbits.get_sign(); - xbits.set_sign(false); + Sign sign = xbits.sign(); + xbits.set_sign(Sign::POS); if (LIBC_UNLIKELY(xbits.is_inf_or_nan())) { if (xbits.is_inf()) - return static_cast(opt_barrier(sign ? -M_MATH_PI_2 : M_MATH_PI_2)); + return static_cast( + opt_barrier(sign.is_neg() ? -M_MATH_PI_2 : M_MATH_PI_2)); else return x; } @@ -45,7 +47,7 @@ LLVM_LIBC_FUNCTION(float, atanf, (float x)) { // |x| == 1.8670953512191772 if (LIBC_UNLIKELY(xbits.uintval() == 0x3feefcfbU)) { int rounding_mode = fputil::quick_get_round(); - if (sign) { + if (sign.is_neg()) { if (rounding_mode == FE_DOWNWARD) { // -1.0790828466415405 return FPBits(0xbf8a1f63U).get_val(); diff --git a/libc/src/math/generic/atanhf.cpp b/libc/src/math/generic/atanhf.cpp index df5f53f392cf3..fd6f5c96b6b4e 100644 --- a/libc/src/math/generic/atanhf.cpp +++ b/libc/src/math/generic/atanhf.cpp @@ -15,8 +15,9 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, atanhf, (float x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; FPBits xbits(x); - bool sign = xbits.get_sign(); + Sign sign = xbits.sign(); uint32_t x_abs = xbits.abs().uintval(); // |x| >= 1.0 diff --git a/libc/src/math/generic/cosf.cpp b/libc/src/math/generic/cosf.cpp index 67b60de03024f..89333ab19e89f 100644 --- a/libc/src/math/generic/cosf.cpp +++ b/libc/src/math/generic/cosf.cpp @@ -42,8 +42,9 @@ static constexpr fputil::ExceptValues COSF_EXCEPTS{{ LLVM_LIBC_FUNCTION(float, cosf, (float x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; FPBits xbits(x); - xbits.set_sign(false); + xbits.set_sign(Sign::POS); uint32_t x_abs = xbits.uintval(); double xd = static_cast(xbits.get_val()); diff --git a/libc/src/math/generic/coshf.cpp b/libc/src/math/generic/coshf.cpp index 4a55b6940ff8c..3b01852e9f544 100644 --- a/libc/src/math/generic/coshf.cpp +++ b/libc/src/math/generic/coshf.cpp @@ -17,8 +17,9 @@ namespace LIBC_NAMESPACE { LLVM_LIBC_FUNCTION(float, coshf, (float x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; FPBits xbits(x); - xbits.set_sign(false); + xbits.set_sign(Sign::POS); x = xbits.get_val(); uint32_t x_u = xbits.uintval(); diff --git a/libc/src/math/generic/erff.cpp b/libc/src/math/generic/erff.cpp index 333ca197dbedb..f120d5646e043 100644 --- a/libc/src/math/generic/erff.cpp +++ b/libc/src/math/generic/erff.cpp @@ -140,7 +140,7 @@ LLVM_LIBC_FUNCTION(float, erff, (float x)) { const float ONE[2] = {1.0f, -1.0f}; const float SMALL[2] = {-0x1.0p-25f, 0x1.0p-25f}; - int sign = static_cast(xbits.get_sign()); + int sign = xbits.is_neg() ? 1 : 0; if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { return (x_abs > 0x7f80'0000) ? x : ONE[sign]; diff --git a/libc/src/math/generic/exp10f_impl.h b/libc/src/math/generic/exp10f_impl.h index a2ec5391ba50a..2861659a6e57e 100644 --- a/libc/src/math/generic/exp10f_impl.h +++ b/libc/src/math/generic/exp10f_impl.h @@ -48,7 +48,7 @@ LIBC_INLINE float exp10f(float x) { return 0.0f; } // x >= log10(2^128) or nan - if (!xbits.get_sign() && (x_u >= 0x421a'209bU)) { + if (xbits.is_pos() && (x_u >= 0x421a'209bU)) { // x is finite if (x_u < 0x7f80'0000U) { int rounding = fputil::quick_get_round(); diff --git a/libc/src/math/generic/exp2f_impl.h b/libc/src/math/generic/exp2f_impl.h index e6fd65264c721..86360840b96e6 100644 --- a/libc/src/math/generic/exp2f_impl.h +++ b/libc/src/math/generic/exp2f_impl.h @@ -71,7 +71,7 @@ LIBC_INLINE float exp2f(float x) { } // x >= 128 - if (!xbits.get_sign()) { + if (xbits.is_pos()) { // x is finite if (x_u < 0x7f80'0000U) { int rounding = fputil::quick_get_round(); diff --git a/libc/src/math/generic/expf.cpp b/libc/src/math/generic/expf.cpp index d0bb681df9e9d..88d408994fe42 100644 --- a/libc/src/math/generic/expf.cpp +++ b/libc/src/math/generic/expf.cpp @@ -56,7 +56,7 @@ LLVM_LIBC_FUNCTION(float, expf, (float x)) { return 0.0f; } // x >= 89 or nan - if (!xbits.get_sign() && (xbits.uintval() >= 0x42b2'0000)) { + if (xbits.is_pos() && (xbits.uintval() >= 0x42b2'0000)) { // x is finite if (xbits.uintval() < 0x7f80'0000U) { int rounding = fputil::quick_get_round(); diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp index 8ab341d55a226..71c4663edd21a 100644 --- a/libc/src/math/generic/expm1.cpp +++ b/libc/src/math/generic/expm1.cpp @@ -275,9 +275,10 @@ double set_exceptional(double x) { LLVM_LIBC_FUNCTION(double, expm1, (double x)) { using FPBits = typename fputil::FPBits; + using Sign = fputil::Sign; FPBits xbits(x); - bool x_sign = xbits.get_sign(); + bool x_is_neg = xbits.is_neg(); uint64_t x_u = xbits.uintval(); // Upper bound: max normal number = 2^1023 * (2 - 2^-52) @@ -392,11 +393,11 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) { // -2^(-hi) double one_scaled = - FPBits::create_value(true, FPBits::EXP_BIAS - hi, 0).get_val(); + FPBits::create_value(Sign::NEG, FPBits::EXP_BIAS - hi, 0).get_val(); // 2^(mid1 + mid2) - 2^(-hi) - DoubleDouble hi_part = x_sign ? fputil::exact_add(one_scaled, exp_mid.hi) - : fputil::exact_add(exp_mid.hi, one_scaled); + DoubleDouble hi_part = x_is_neg ? fputil::exact_add(one_scaled, exp_mid.hi) + : fputil::exact_add(exp_mid.hi, one_scaled); hi_part.lo += exp_mid.lo; @@ -437,7 +438,9 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) { double lo = fputil::multiply_add(p, mid_lo, hi_part.lo); - uint64_t err = x_sign ? (static_cast(-hi) << 52) : 0; + // TODO: The following line leaks encoding abstraction. Use FPBits methods + // instead. + uint64_t err = x_is_neg ? (static_cast(-hi) << 52) : 0; double err_d = cpp::bit_cast(ERR_D + err); diff --git a/libc/src/math/generic/expm1f.cpp b/libc/src/math/generic/expm1f.cpp index 3739a7bbbaa84..c6e0663ec46c3 100644 --- a/libc/src/math/generic/expm1f.cpp +++ b/libc/src/math/generic/expm1f.cpp @@ -51,7 +51,7 @@ LLVM_LIBC_FUNCTION(float, expm1f, (float x)) { // When |x| > 25*log(2), or nan if (LIBC_UNLIKELY(x_abs >= 0x418a'a123U)) { // x < log(2^-25) - if (xbits.get_sign()) { + if (xbits.is_neg()) { // exp(-Inf) = 0 if (xbits.is_inf()) return -1.0f; diff --git a/libc/src/math/generic/inv_trigf_utils.h b/libc/src/math/generic/inv_trigf_utils.h index 4e85d4ae08d57..20f912de2ac00 100644 --- a/libc/src/math/generic/inv_trigf_utils.h +++ b/libc/src/math/generic/inv_trigf_utils.h @@ -38,18 +38,19 @@ extern const double ATAN_K[5]; // x should be positive, normal finite value LIBC_INLINE double atan_eval(double x) { using FPB = fputil::FPBits; + using Sign = fputil::Sign; // Added some small value to umin and umax mantissa to avoid possible rounding // errors. FPB::StorageType umin = - FPB::create_value(false, FPB::EXP_BIAS - ATAN_T_BITS - 1, + FPB::create_value(Sign::POS, FPB::EXP_BIAS - ATAN_T_BITS - 1, 0x100000000000UL) .uintval(); FPB::StorageType umax = - FPB::create_value(false, FPB::EXP_BIAS + ATAN_T_BITS, 0xF000000000000UL) + FPB::create_value(Sign::POS, FPB::EXP_BIAS + ATAN_T_BITS, + 0xF000000000000UL) .uintval(); FPB bs(x); - bool sign = bs.get_sign(); auto x_abs = bs.abs().uintval(); if (x_abs <= umin) { @@ -64,7 +65,7 @@ LIBC_INLINE double atan_eval(double x) { double pe = LIBC_NAMESPACE::fputil::polyeval( one_over_x2, ATAN_K[0], ATAN_K[1], ATAN_K[2], ATAN_K[3]); return fputil::multiply_add(pe, one_over_x_m, - sign ? (-M_MATH_PI_2) : (M_MATH_PI_2)); + bs.is_neg() ? (-M_MATH_PI_2) : (M_MATH_PI_2)); } double pos_x = FPB(x_abs).get_val(); @@ -86,7 +87,7 @@ LIBC_INLINE double atan_eval(double x) { result = M_MATH_PI_2 - fputil::multiply_add(pe, v, ATAN_T[val - 1]); else result = fputil::multiply_add(pe, v, ATAN_T[val - 1]); - return sign ? -result : result; + return bs.is_neg() ? -result : result; } // > Q = fpminimax(asin(x)/x, [|0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20|], diff --git a/libc/src/math/generic/log.cpp b/libc/src/math/generic/log.cpp index 8f22fdea93217..5b3f48c85614b 100644 --- a/libc/src/math/generic/log.cpp +++ b/libc/src/math/generic/log.cpp @@ -747,9 +747,9 @@ LLVM_LIBC_FUNCTION(double, log, (double x)) { // return -Inf and raise FE_DIVBYZERO. fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits_t::neg_inf()); + return static_cast(FPBits_t::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); return FPBits_t::build_quiet_nan(0); diff --git a/libc/src/math/generic/log10.cpp b/libc/src/math/generic/log10.cpp index df82f24dc6967..b7b49e2b3ac4b 100644 --- a/libc/src/math/generic/log10.cpp +++ b/libc/src/math/generic/log10.cpp @@ -748,9 +748,9 @@ LLVM_LIBC_FUNCTION(double, log10, (double x)) { // return -Inf and raise FE_DIVBYZERO. fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits_t::neg_inf()); + return static_cast(FPBits_t::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); return FPBits_t::build_quiet_nan(0); diff --git a/libc/src/math/generic/log10f.cpp b/libc/src/math/generic/log10f.cpp index da69f7f5ad4d9..46505f4e07e67 100644 --- a/libc/src/math/generic/log10f.cpp +++ b/libc/src/math/generic/log10f.cpp @@ -165,9 +165,9 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) { // Return -inf and raise FE_DIVBYZERO fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits::neg_inf()); + return static_cast(FPBits::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { // Return NaN and raise FE_INVALID fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/log1p.cpp b/libc/src/math/generic/log1p.cpp index 74eed6ceeb28d..af651d3e5bca2 100644 --- a/libc/src/math/generic/log1p.cpp +++ b/libc/src/math/generic/log1p.cpp @@ -892,9 +892,9 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) { // x = -1.0 fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits_t::neg_inf()); + return static_cast(FPBits_t::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { // x < -1.0 fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp index 891700d5ed08c..0812569c624b8 100644 --- a/libc/src/math/generic/log1pf.cpp +++ b/libc/src/math/generic/log1pf.cpp @@ -44,7 +44,7 @@ LIBC_INLINE float log(double x) { uint64_t x_u = xbits.uintval(); if (LIBC_UNLIKELY(x_u > FPBits::MAX_NORMAL)) { - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); return fputil::FPBits::build_quiet_nan(0); @@ -106,7 +106,7 @@ LLVM_LIBC_FUNCTION(float, log1pf, (float x)) { case 0xbf800000U: // x = -1.0 fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(fputil::FPBits::neg_inf()); + return static_cast(fputil::FPBits::inf(fputil::Sign::NEG)); #ifndef LIBC_TARGET_CPU_HAS_FMA case 0x4cc1c80bU: // x = 0x1.839016p+26f return fputil::round_result_slightly_down(0x1.26fc04p+4f); diff --git a/libc/src/math/generic/log2.cpp b/libc/src/math/generic/log2.cpp index 1427d1934db90..261078f710742 100644 --- a/libc/src/math/generic/log2.cpp +++ b/libc/src/math/generic/log2.cpp @@ -869,9 +869,9 @@ LLVM_LIBC_FUNCTION(double, log2, (double x)) { // return -Inf and raise FE_DIVBYZERO. fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits_t::neg_inf()); + return static_cast(FPBits_t::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); return FPBits_t::build_quiet_nan(0); diff --git a/libc/src/math/generic/log2f.cpp b/libc/src/math/generic/log2f.cpp index 07dedba85e627..9cddbb9e8ea48 100644 --- a/libc/src/math/generic/log2f.cpp +++ b/libc/src/math/generic/log2f.cpp @@ -72,9 +72,9 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) { if (xbits.is_zero()) { fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits::neg_inf()); + return static_cast(FPBits::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { fputil::set_errno_if_required(EDOM); fputil::raise_except(FE_INVALID); return FPBits::build_quiet_nan(0); diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp index f1f93468479b1..8ccb55dcc9e33 100644 --- a/libc/src/math/generic/logf.cpp +++ b/libc/src/math/generic/logf.cpp @@ -84,7 +84,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) { // Return -inf and raise FE_DIVBYZERO fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits::neg_inf()); + return static_cast(FPBits::inf(fputil::Sign::NEG)); } // Normalize denormal inputs. xbits = FPBits(xbits.get_val() * 0x1.0p23f); @@ -117,9 +117,9 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) { // Return -inf and raise FE_DIVBYZERO fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_DIVBYZERO); - return static_cast(FPBits::neg_inf()); + return static_cast(FPBits::inf(fputil::Sign::NEG)); } - if (xbits.get_sign() && !xbits.is_nan()) { + if (xbits.is_neg() && !xbits.is_nan()) { // Return NaN and raise FE_INVALID fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_INVALID); diff --git a/libc/src/math/generic/powf.cpp b/libc/src/math/generic/powf.cpp index 49f33b71c5600..932f1d70c33e8 100644 --- a/libc/src/math/generic/powf.cpp +++ b/libc/src/math/generic/powf.cpp @@ -424,6 +424,7 @@ LIBC_INLINE bool larger_exponent(double a, double b) { double powf_double_double(int idx_x, double dx, double y6, double lo6_hi, const DoubleDouble &exp2_hi_mid) { using DoubleBits = typename fputil::FPBits; + using Sign = fputil::Sign; // Perform a second range reduction step: // idx2 = round(2^14 * (dx + 2^-8)) = round ( dx * 2^14 + 2^6) // dx2 = (1 + dx) * r2 - 1 @@ -495,8 +496,8 @@ double powf_double_double(int idx_x, double dx, double y6, double lo6_hi, // Round to odd. uint64_t r_bits = cpp::bit_cast(r.hi); if (LIBC_UNLIKELY(((r_bits & 0xfff'ffff) == 0) && (r.lo != 0.0))) { - bool hi_sign = DoubleBits(r.hi).get_sign(); - bool lo_sign = DoubleBits(r.lo).get_sign(); + Sign hi_sign = DoubleBits(r.hi).sign(); + Sign lo_sign = DoubleBits(r.lo).sign(); if (hi_sign == lo_sign) { ++r_bits; } else if ((r_bits & DoubleBits::FRACTION_MASK) > 0) { @@ -512,6 +513,7 @@ double powf_double_double(int idx_x, double dx, double y6, double lo6_hi, LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { using FloatBits = typename fputil::FPBits; using DoubleBits = typename fputil::FPBits; + using Sign = fputil::Sign; FloatBits xbits(x), ybits(y); uint32_t x_u = xbits.uintval(); @@ -605,28 +607,28 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { return generic::exp10f(y); } - bool x_sign = x_u >= FloatBits::SIGN_MASK; + const bool x_is_neg = x_u >= FloatBits::SIGN_MASK; switch (x_abs) { case 0x0000'0000: { // x = +-0.0f - bool x_sign = (x_u >= FloatBits::SIGN_MASK); - bool out_sign = x_sign && is_odd_integer(FloatBits(y_u).get_val()); + const bool out_is_neg = + x_is_neg && is_odd_integer(FloatBits(y_u).get_val()); if (y_u > 0x8000'0000U) { // pow(0, negative number) = inf fputil::set_errno_if_required(EDOM); fputil::raise_except_if_required(FE_DIVBYZERO); - return FloatBits::inf(out_sign); + return FloatBits::inf(out_is_neg ? Sign::NEG : Sign::POS); } // pow(0, positive number) = 0 - return out_sign ? -0.0f : 0.0f; + return out_is_neg ? -0.0f : 0.0f; } case 0x7f80'0000: { // x = +-Inf - bool x_sign = (x_u >= FloatBits::SIGN_MASK); - bool out_sign = x_sign && is_odd_integer(FloatBits(y_u).get_val()); + const bool out_is_neg = + x_is_neg && is_odd_integer(FloatBits(y_u).get_val()); if (y_u >= FloatBits::SIGN_MASK) { - return out_sign ? -0.0f : 0.0f; + return out_is_neg ? -0.0f : 0.0f; } - return FloatBits::inf(out_sign); + return FloatBits::inf(out_is_neg ? Sign::NEG : Sign::POS); } } @@ -643,7 +645,7 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) { } // x is finite and negative, and y is a finite integer. - if (x_sign) { + if (x_is_neg) { if (is_integer(y)) { x = -x; if (is_odd_integer(y)) { diff --git a/libc/src/math/generic/sinf.cpp b/libc/src/math/generic/sinf.cpp index 6fc1abb83e2e7..9e574d4e57240 100644 --- a/libc/src/math/generic/sinf.cpp +++ b/libc/src/math/generic/sinf.cpp @@ -128,10 +128,10 @@ LLVM_LIBC_FUNCTION(float, sinf, (float x)) { if (LIBC_UNLIKELY(x_abs == 0x4619'9998U)) { // x = 0x1.33333p13 float r = -0x1.63f4bap-2f; int rounding = fputil::quick_get_round(); - bool sign = xbits.get_sign(); - if ((rounding == FE_DOWNWARD && !sign) || (rounding == FE_UPWARD && sign)) + if ((rounding == FE_DOWNWARD && xbits.is_pos()) || + (rounding == FE_UPWARD && xbits.is_neg())) r = -0x1.63f4bcp-2f; - return xbits.get_sign() ? -r : r; + return xbits.is_neg() ? -r : r; } if (LIBC_UNLIKELY(x_abs >= 0x7f80'0000U)) { diff --git a/libc/src/math/generic/sinhf.cpp b/libc/src/math/generic/sinhf.cpp index d64519d0ec79b..b3850c6742706 100644 --- a/libc/src/math/generic/sinhf.cpp +++ b/libc/src/math/generic/sinhf.cpp @@ -53,9 +53,8 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { if (xbits.is_inf()) return x; - bool sign = xbits.get_sign(); int rounding = fputil::quick_get_round(); - if (sign) { + if (xbits.is_neg()) { if (LIBC_UNLIKELY(rounding == FE_UPWARD || rounding == FE_TOWARDZERO)) return -FPBits::max_normal(); } else { @@ -66,7 +65,7 @@ LLVM_LIBC_FUNCTION(float, sinhf, (float x)) { fputil::set_errno_if_required(ERANGE); fputil::raise_except_if_required(FE_OVERFLOW); - return x + FPBits::inf(sign); + return x + FPBits::inf(xbits.sign()); } // sinh(x) = (e^x - e^(-x)) / 2. diff --git a/libc/src/math/generic/tanhf.cpp b/libc/src/math/generic/tanhf.cpp index 48e78ec2383f2..0efd0cefebe57 100644 --- a/libc/src/math/generic/tanhf.cpp +++ b/libc/src/math/generic/tanhf.cpp @@ -25,6 +25,8 @@ LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { FPBits xbits(x); uint32_t x_abs = xbits.abs().uintval(); + const int sign_index = xbits.is_neg() ? 1 : 0; + // When |x| >= 15, or x is inf or nan, or |x| <= 0.078125 if (LIBC_UNLIKELY((x_abs >= 0x4170'0000U) || (x_abs <= 0x3da0'0000U))) { if (x_abs <= 0x3da0'0000U) { @@ -57,13 +59,10 @@ LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { constexpr float SIGNS[2][2] = {{1.0f, -0x1.0p-25f}, {-1.0f, 0x1.0p-25f}}; - bool sign = xbits.get_sign(); - int idx = static_cast(sign); - if (LIBC_UNLIKELY(xbits.is_inf())) - return SIGNS[idx][0]; + return SIGNS[sign_index][0]; - return SIGNS[idx][0] + SIGNS[idx][1]; + return SIGNS[sign_index][0] + SIGNS[sign_index][1]; } // Range reduction: e^(2x) = 2^(hi + mid) * e^lo @@ -83,7 +82,7 @@ LLVM_LIBC_FUNCTION(float, tanhf, (float x)) { constexpr double HALF_WAY[2] = {-0.5, 0.5}; mk = static_cast( - fputil::multiply_add(xd, -LOG2_E_EXP2_6, HALF_WAY[xbits.get_sign()])); + fputil::multiply_add(xd, -LOG2_E_EXP2_6, HALF_WAY[sign_index])); k = static_cast(-mk); #endif // LIBC_TARGET_CPU_HAS_NEAREST_INT // -hi = floor(-k * 2^(-MID_BITS)) diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h index cfa351cf017ae..6171d1d5946e6 100644 --- a/libc/src/stdio/printf_core/float_dec_converter.h +++ b/libc/src/stdio/printf_core/float_dec_converter.h @@ -49,7 +49,7 @@ constexpr char DECIMAL_POINT = '.'; enum class RoundDirection { Up, Down, Even }; LIBC_INLINE RoundDirection get_round_direction(int last_digit, bool truncated, - bool is_negative) { + fputil::Sign sign) { switch (fputil::quick_get_round()) { case FE_TONEAREST: // Round to nearest, if it's exactly halfway then round to even. @@ -59,18 +59,18 @@ LIBC_INLINE RoundDirection get_round_direction(int last_digit, bool truncated, return !truncated ? RoundDirection::Even : RoundDirection::Up; } case FE_DOWNWARD: - if (is_negative && (truncated || last_digit > 0)) { + if (sign.is_neg() && (truncated || last_digit > 0)) { return RoundDirection::Up; } else { return RoundDirection::Down; } case FE_UPWARD: - if (!is_negative && (truncated || last_digit > 0)) { + if (sign.is_pos() && (truncated || last_digit > 0)) { return RoundDirection::Up; } else { return RoundDirection::Down; } - return is_negative ? RoundDirection::Down : RoundDirection::Up; + return sign.is_neg() ? RoundDirection::Down : RoundDirection::Up; case FE_TOWARDZERO: return RoundDirection::Down; default: @@ -474,12 +474,11 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer, fputil::FPBits float_bits) { // signed because later we use -FRACTION_LEN constexpr int32_t FRACTION_LEN = fputil::FPBits::FRACTION_LEN; - bool is_negative = float_bits.get_sign(); int exponent = float_bits.get_explicit_exponent(); char sign_char = 0; - if (is_negative) + if (float_bits.is_neg()) sign_char = '-'; else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN) sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX @@ -567,7 +566,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer, const bool truncated = !zero_after_digits( exponent - FRACTION_LEN, precision, float_bits.get_explicit_mantissa(), FRACTION_LEN); - round = get_round_direction(last_digit, truncated, is_negative); + round = get_round_direction(last_digit, truncated, float_bits.sign()); RET_IF_RESULT_NEGATIVE( float_writer.write_last_block(digits, maximum, round)); @@ -587,7 +586,6 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer, fputil::FPBits float_bits) { // signed because later we use -FRACTION_LEN constexpr int32_t FRACTION_LEN = fputil::FPBits::FRACTION_LEN; - bool is_negative = float_bits.get_sign(); int exponent = float_bits.get_explicit_exponent(); StorageType mantissa = float_bits.get_explicit_mantissa(); @@ -595,7 +593,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer, char sign_char = 0; - if (is_negative) + if (float_bits.is_neg()) sign_char = '-'; else if ((to_conv.flags & FormatFlags::FORCE_SIGN) == FormatFlags::FORCE_SIGN) sign_char = '+'; // FORCE_SIGN has precedence over SPACE_PREFIX @@ -735,7 +733,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer, float_bits.get_explicit_mantissa(), FRACTION_LEN); } } - round = get_round_direction(last_digit, truncated, is_negative); + round = get_round_direction(last_digit, truncated, float_bits.sign()); RET_IF_RESULT_NEGATIVE(float_writer.write_last_block( digits, maximum, round, final_exponent, a + 'E' - 'A')); @@ -750,7 +748,6 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer, fputil::FPBits float_bits) { // signed because later we use -FRACTION_LEN constexpr int32_t FRACTION_LEN = fputil::FPBits::FRACTION_LEN; - bool is_negative = float_bits.get_sign(); int exponent = float_bits.get_explicit_exponent(); StorageType mantissa = float_bits.get_explicit_mantissa(); @@ -983,7 +980,7 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer, } } - round = get_round_direction(last_digit, truncated, is_negative); + round = get_round_direction(last_digit, truncated, float_bits.sign()); bool round_up; if (round == RoundDirection::Up) { diff --git a/libc/src/stdio/printf_core/float_hex_converter.h b/libc/src/stdio/printf_core/float_hex_converter.h index 5ccae81b430c5..68a4ba6209d09 100644 --- a/libc/src/stdio/printf_core/float_hex_converter.h +++ b/libc/src/stdio/printf_core/float_hex_converter.h @@ -41,7 +41,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, fraction_bits = LDBits::FRACTION_LEN; LDBits::StorageType float_raw = to_conv.conv_val_raw; LDBits float_bits(float_raw); - is_negative = float_bits.get_sign(); + is_negative = float_bits.is_neg(); exponent = float_bits.get_explicit_exponent(); mantissa = float_bits.get_explicit_mantissa(); is_inf_or_nan = float_bits.is_inf_or_nan(); @@ -51,7 +51,7 @@ LIBC_INLINE int convert_float_hex_exp(Writer *writer, LBits::StorageType float_raw = static_cast(to_conv.conv_val_raw); LBits float_bits(float_raw); - is_negative = float_bits.get_sign(); + is_negative = float_bits.is_neg(); exponent = float_bits.get_explicit_exponent(); mantissa = float_bits.get_explicit_mantissa(); is_inf_or_nan = float_bits.is_inf_or_nan(); diff --git a/libc/src/stdio/printf_core/float_inf_nan_converter.h b/libc/src/stdio/printf_core/float_inf_nan_converter.h index 8669dc374cb29..f755ef6e31f26 100644 --- a/libc/src/stdio/printf_core/float_inf_nan_converter.h +++ b/libc/src/stdio/printf_core/float_inf_nan_converter.h @@ -32,13 +32,13 @@ LIBC_INLINE int convert_inf_nan(Writer *writer, const FormatSection &to_conv) { if (to_conv.length_modifier == LengthModifier::L) { fputil::FPBits::StorageType float_raw = to_conv.conv_val_raw; fputil::FPBits float_bits(float_raw); - is_negative = float_bits.get_sign(); + is_negative = float_bits.is_neg(); mantissa = float_bits.get_mantissa(); } else { fputil::FPBits::StorageType float_raw = static_cast::StorageType>(to_conv.conv_val_raw); fputil::FPBits float_bits(float_raw); - is_negative = float_bits.get_sign(); + is_negative = float_bits.is_neg(); mantissa = float_bits.get_mantissa(); } diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h index 003de7eb72ac8..26b8e3e60bdfd 100644 --- a/libc/test/UnitTest/FPMatcher.h +++ b/libc/test/UnitTest/FPMatcher.h @@ -63,14 +63,15 @@ template FPMatcher getMatcher(T expectedValue) { template struct FPTest : public Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; static constexpr StorageType STORAGE_MAX = LIBC_NAMESPACE::cpp::numeric_limits::max(); - static constexpr T zero = FPBits::zero(); - static constexpr T neg_zero = FPBits::neg_zero(); + static constexpr T zero = FPBits::zero(Sign::POS); + static constexpr T neg_zero = FPBits::zero(Sign::NEG); static constexpr T aNaN = FPBits::build_quiet_nan(1); static constexpr T sNaN = FPBits::build_nan(1); - static constexpr T inf = FPBits::inf(); - static constexpr T neg_inf = FPBits::neg_inf(); + static constexpr T inf = FPBits::inf(Sign::POS); + static constexpr T neg_inf = FPBits::inf(Sign::NEG); static constexpr T min_normal = FPBits::min_normal(); static constexpr T max_normal = FPBits::max_normal(); static constexpr T min_denormal = FPBits::min_denormal(); @@ -91,14 +92,15 @@ template struct FPTest : public Test { #define DECLARE_SPECIAL_CONSTANTS(T) \ using FPBits = LIBC_NAMESPACE::fputil::FPBits; \ using StorageType = typename FPBits::StorageType; \ + using Sign = LIBC_NAMESPACE::fputil::Sign; \ static constexpr StorageType STORAGE_MAX = \ LIBC_NAMESPACE::cpp::numeric_limits::max(); \ - const T zero = FPBits::zero(); \ - const T neg_zero = FPBits::neg_zero(); \ + const T zero = FPBits::zero(Sign::POS); \ + const T neg_zero = FPBits::zero(Sign::NEG); \ const T aNaN = FPBits::build_quiet_nan(1); \ const T sNaN = FPBits::build_nan(1); \ - const T inf = FPBits::inf(); \ - const T neg_inf = FPBits::neg_inf(); \ + const T inf = FPBits::inf(Sign::POS); \ + const T neg_inf = FPBits::inf(Sign::NEG); \ const T min_normal = FPBits::min_normal(); \ const T max_normal = FPBits::max_normal(); \ const T min_denormal = FPBits::min_denormal(); \ diff --git a/libc/test/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp index a955f460cf3bb..f0b155085dabf 100644 --- a/libc/test/src/__support/FPUtil/fpbits_test.cpp +++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp @@ -11,6 +11,7 @@ #include "test/UnitTest/Test.h" using LIBC_NAMESPACE::fputil::FPBits; +using LIBC_NAMESPACE::fputil::Sign; TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary16) { using LIBC_NAMESPACE::fputil::FPType; @@ -228,15 +229,17 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) { TEST(LlvmLibcFPBitsTest, FloatType) { using FloatBits = FPBits; - EXPECT_STREQ(LIBC_NAMESPACE::str(FloatBits(FloatBits::inf())).c_str(), - "(+Infinity)"); - EXPECT_STREQ(LIBC_NAMESPACE::str(FloatBits(FloatBits::neg_inf())).c_str(), - "(-Infinity)"); + EXPECT_STREQ( + LIBC_NAMESPACE::str(FloatBits(FloatBits::inf(Sign::POS))).c_str(), + "(+Infinity)"); + EXPECT_STREQ( + LIBC_NAMESPACE::str(FloatBits(FloatBits::inf(Sign::NEG))).c_str(), + "(-Infinity)"); EXPECT_STREQ(LIBC_NAMESPACE::str(FloatBits(FloatBits::build_nan(1))).c_str(), "(NaN)"); FloatBits zero(0.0f); - EXPECT_EQ(zero.get_sign(), false); + EXPECT_TRUE(zero.is_pos()); EXPECT_EQ(zero.get_biased_exponent(), static_cast(0)); EXPECT_EQ(zero.get_mantissa(), static_cast(0)); EXPECT_EQ(zero.uintval(), static_cast(0x00000000)); @@ -244,7 +247,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) { "0x00000000 = (S: 0, E: 0x0000, M: 0x00000000)"); FloatBits negzero(-0.0f); - EXPECT_EQ(negzero.get_sign(), true); + EXPECT_TRUE(negzero.is_neg()); EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0)); EXPECT_EQ(negzero.get_mantissa(), static_cast(0)); EXPECT_EQ(negzero.uintval(), static_cast(0x80000000)); @@ -252,7 +255,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) { "0x80000000 = (S: 1, E: 0x0000, M: 0x00000000)"); FloatBits one(1.0f); - EXPECT_EQ(one.get_sign(), false); + EXPECT_TRUE(one.is_pos()); EXPECT_EQ(one.get_biased_exponent(), static_cast(0x7F)); EXPECT_EQ(one.get_mantissa(), static_cast(0)); EXPECT_EQ(one.uintval(), static_cast(0x3F800000)); @@ -260,7 +263,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) { "0x3F800000 = (S: 0, E: 0x007F, M: 0x00000000)"); FloatBits negone(-1.0f); - EXPECT_EQ(negone.get_sign(), true); + EXPECT_TRUE(negone.is_neg()); EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x7F)); EXPECT_EQ(negone.get_mantissa(), static_cast(0)); EXPECT_EQ(negone.uintval(), static_cast(0xBF800000)); @@ -268,7 +271,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) { "0xBF800000 = (S: 1, E: 0x007F, M: 0x00000000)"); FloatBits num(1.125f); - EXPECT_EQ(num.get_sign(), false); + EXPECT_TRUE(num.is_pos()); EXPECT_EQ(num.get_biased_exponent(), static_cast(0x7F)); EXPECT_EQ(num.get_mantissa(), static_cast(0x00100000)); EXPECT_EQ(num.uintval(), static_cast(0x3F900000)); @@ -276,7 +279,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) { "0x3F900000 = (S: 0, E: 0x007F, M: 0x00100000)"); FloatBits negnum(-1.125f); - EXPECT_EQ(negnum.get_sign(), true); + EXPECT_TRUE(negnum.is_neg()); EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x7F)); EXPECT_EQ(negnum.get_mantissa(), static_cast(0x00100000)); EXPECT_EQ(negnum.uintval(), static_cast(0xBF900000)); @@ -290,16 +293,18 @@ TEST(LlvmLibcFPBitsTest, FloatType) { TEST(LlvmLibcFPBitsTest, DoubleType) { using DoubleBits = FPBits; - EXPECT_STREQ(LIBC_NAMESPACE::str(DoubleBits(DoubleBits::inf())).c_str(), - "(+Infinity)"); - EXPECT_STREQ(LIBC_NAMESPACE::str(DoubleBits(DoubleBits::neg_inf())).c_str(), - "(-Infinity)"); + EXPECT_STREQ( + LIBC_NAMESPACE::str(DoubleBits(DoubleBits::inf(Sign::POS))).c_str(), + "(+Infinity)"); + EXPECT_STREQ( + LIBC_NAMESPACE::str(DoubleBits(DoubleBits::inf(Sign::NEG))).c_str(), + "(-Infinity)"); EXPECT_STREQ( LIBC_NAMESPACE::str(DoubleBits(DoubleBits::build_nan(1))).c_str(), "(NaN)"); DoubleBits zero(0.0); - EXPECT_EQ(zero.get_sign(), false); + EXPECT_TRUE(zero.is_pos()); EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000)); EXPECT_EQ(zero.uintval(), static_cast(0x0000000000000000)); @@ -307,7 +312,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) { "0x0000000000000000 = (S: 0, E: 0x0000, M: 0x0000000000000000)"); DoubleBits negzero(-0.0); - EXPECT_EQ(negzero.get_sign(), true); + EXPECT_TRUE(negzero.is_neg()); EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000)); EXPECT_EQ(negzero.uintval(), static_cast(0x8000000000000000)); @@ -315,7 +320,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) { "0x8000000000000000 = (S: 1, E: 0x0000, M: 0x0000000000000000)"); DoubleBits one(1.0); - EXPECT_EQ(one.get_sign(), false); + EXPECT_TRUE(one.is_pos()); EXPECT_EQ(one.get_biased_exponent(), static_cast(0x03FF)); EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000)); EXPECT_EQ(one.uintval(), static_cast(0x3FF0000000000000)); @@ -323,7 +328,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) { "0x3FF0000000000000 = (S: 0, E: 0x03FF, M: 0x0000000000000000)"); DoubleBits negone(-1.0); - EXPECT_EQ(negone.get_sign(), true); + EXPECT_TRUE(negone.is_neg()); EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x03FF)); EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000)); EXPECT_EQ(negone.uintval(), static_cast(0xBFF0000000000000)); @@ -331,7 +336,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) { "0xBFF0000000000000 = (S: 1, E: 0x03FF, M: 0x0000000000000000)"); DoubleBits num(1.125); - EXPECT_EQ(num.get_sign(), false); + EXPECT_TRUE(num.is_pos()); EXPECT_EQ(num.get_biased_exponent(), static_cast(0x03FF)); EXPECT_EQ(num.get_mantissa(), static_cast(0x0002000000000000)); EXPECT_EQ(num.uintval(), static_cast(0x3FF2000000000000)); @@ -339,7 +344,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) { "0x3FF2000000000000 = (S: 0, E: 0x03FF, M: 0x0002000000000000)"); DoubleBits negnum(-1.125); - EXPECT_EQ(negnum.get_sign(), true); + EXPECT_TRUE(negnum.is_neg()); EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x03FF)); EXPECT_EQ(negnum.get_mantissa(), static_cast(0x0002000000000000)); EXPECT_EQ(negnum.uintval(), static_cast(0xBFF2000000000000)); @@ -358,17 +363,19 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { return; // The tests for the "double" type cover for this case. EXPECT_STREQ( - LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::inf())).c_str(), + LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::inf(Sign::POS))) + .c_str(), "(+Infinity)"); EXPECT_STREQ( - LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::neg_inf())).c_str(), + LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::inf(Sign::NEG))) + .c_str(), "(-Infinity)"); EXPECT_STREQ( LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::build_nan(1))).c_str(), "(NaN)"); LongDoubleBits zero(0.0l); - EXPECT_EQ(zero.get_sign(), false); + EXPECT_TRUE(zero.is_pos()); EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -379,7 +386,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { "(S: 0, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)"); LongDoubleBits negzero(-0.0l); - EXPECT_EQ(negzero.get_sign(), true); + EXPECT_TRUE(negzero.is_neg()); EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -390,7 +397,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { "(S: 1, E: 0x0000, I: 0, M: 0x00000000000000000000000000000000)"); LongDoubleBits one(1.0l); - EXPECT_EQ(one.get_sign(), false); + EXPECT_TRUE(one.is_pos()); EXPECT_EQ(one.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); EXPECT_EQ(one.uintval(), static_cast(0x3FFF8) << 60); @@ -400,7 +407,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)"); LongDoubleBits negone(-1.0l); - EXPECT_EQ(negone.get_sign(), true); + EXPECT_TRUE(negone.is_neg()); EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -411,7 +418,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { "(S: 1, E: 0x3FFF, I: 1, M: 0x00000000000000000000000000000000)"); LongDoubleBits num(1.125l); - EXPECT_EQ(num.get_sign(), false); + EXPECT_TRUE(num.is_pos()); EXPECT_EQ(num.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(num.get_mantissa(), static_cast(0x1) << 60); EXPECT_EQ(num.uintval(), static_cast(0x3FFF9) << 60); @@ -421,7 +428,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) { "(S: 0, E: 0x3FFF, I: 1, M: 0x00000000000000001000000000000000)"); LongDoubleBits negnum(-1.125l); - EXPECT_EQ(negnum.get_sign(), true); + EXPECT_TRUE(negnum.is_neg()); EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(negnum.get_mantissa(), static_cast(0x1) << 60); EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF9) << 60); @@ -441,17 +448,19 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { using LongDoubleBits = FPBits; EXPECT_STREQ( - LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::inf())).c_str(), + LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::inf(Sign::POS))) + .c_str(), "(+Infinity)"); EXPECT_STREQ( - LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::neg_inf())).c_str(), + LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::inf(Sign::NEG))) + .c_str(), "(-Infinity)"); EXPECT_STREQ( LIBC_NAMESPACE::str(LongDoubleBits(LongDoubleBits::build_nan(1))).c_str(), "(NaN)"); LongDoubleBits zero(0.0l); - EXPECT_EQ(zero.get_sign(), false); + EXPECT_TRUE(zero.is_pos()); EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -461,7 +470,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)"); LongDoubleBits negzero(-0.0l); - EXPECT_EQ(negzero.get_sign(), true); + EXPECT_TRUE(negzero.is_neg()); EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -471,7 +480,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)"); LongDoubleBits one(1.0l); - EXPECT_EQ(one.get_sign(), false); + EXPECT_TRUE(one.is_pos()); EXPECT_EQ(one.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); EXPECT_EQ(one.uintval(), static_cast(0x3FFF) << 112); @@ -480,7 +489,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); LongDoubleBits negone(-1.0l); - EXPECT_EQ(negone.get_sign(), true); + EXPECT_TRUE(negone.is_neg()); EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -490,7 +499,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); LongDoubleBits num(1.125l); - EXPECT_EQ(num.get_sign(), false); + EXPECT_TRUE(num.is_pos()); EXPECT_EQ(num.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(num.get_mantissa(), static_cast(0x2) << 108); EXPECT_EQ(num.uintval(), static_cast(0x3FFF2) << 108); @@ -499,7 +508,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); LongDoubleBits negnum(-1.125l); - EXPECT_EQ(negnum.get_sign(), true); + EXPECT_TRUE(negnum.is_neg()); EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(negnum.get_mantissa(), static_cast(0x2) << 108); EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF2) << 108); @@ -517,17 +526,18 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) { TEST(LlvmLibcFPBitsTest, Float128Type) { using Float128Bits = FPBits; - EXPECT_STREQ(LIBC_NAMESPACE::str(Float128Bits(Float128Bits::inf())).c_str(), - "(+Infinity)"); EXPECT_STREQ( - LIBC_NAMESPACE::str(Float128Bits(Float128Bits::neg_inf())).c_str(), + LIBC_NAMESPACE::str(Float128Bits(Float128Bits::inf(Sign::POS))).c_str(), + "(+Infinity)"); + EXPECT_STREQ( + LIBC_NAMESPACE::str(Float128Bits(Float128Bits::inf(Sign::NEG))).c_str(), "(-Infinity)"); EXPECT_STREQ( LIBC_NAMESPACE::str(Float128Bits(Float128Bits::build_nan(1))).c_str(), "(NaN)"); Float128Bits zero(Float128Bits::zero()); - EXPECT_EQ(zero.get_sign(), false); + EXPECT_TRUE(zero.is_pos()); EXPECT_EQ(zero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(zero.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -536,8 +546,8 @@ TEST(LlvmLibcFPBitsTest, Float128Type) { "0x00000000000000000000000000000000 = " "(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)"); - Float128Bits negzero(Float128Bits::neg_zero()); - EXPECT_EQ(negzero.get_sign(), true); + Float128Bits negzero(Float128Bits::zero(Sign::NEG)); + EXPECT_TRUE(negzero.is_neg()); EXPECT_EQ(negzero.get_biased_exponent(), static_cast(0x0000)); EXPECT_EQ(negzero.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -547,7 +557,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) { "(S: 1, E: 0x0000, M: 0x00000000000000000000000000000000)"); Float128Bits one(float128(1.0)); - EXPECT_EQ(one.get_sign(), false); + EXPECT_TRUE(one.is_pos()); EXPECT_EQ(one.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(one.get_mantissa(), static_cast(0x0000000000000000) << 64); EXPECT_EQ(one.uintval(), static_cast(0x3FFF) << 112); @@ -556,7 +566,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) { "(S: 0, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); Float128Bits negone(float128(-1.0)); - EXPECT_EQ(negone.get_sign(), true); + EXPECT_TRUE(negone.is_neg()); EXPECT_EQ(negone.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(negone.get_mantissa(), static_cast(0x0000000000000000) << 64); @@ -566,7 +576,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) { "(S: 1, E: 0x3FFF, M: 0x00000000000000000000000000000000)"); Float128Bits num(float128(1.125)); - EXPECT_EQ(num.get_sign(), false); + EXPECT_TRUE(num.is_pos()); EXPECT_EQ(num.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(num.get_mantissa(), static_cast(0x2) << 108); EXPECT_EQ(num.uintval(), static_cast(0x3FFF2) << 108); @@ -575,7 +585,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) { "(S: 0, E: 0x3FFF, M: 0x00002000000000000000000000000000)"); Float128Bits negnum(float128(-1.125)); - EXPECT_EQ(negnum.get_sign(), true); + EXPECT_TRUE(negnum.is_neg()); EXPECT_EQ(negnum.get_biased_exponent(), static_cast(0x3FFF)); EXPECT_EQ(negnum.get_mantissa(), static_cast(0x2) << 108); EXPECT_EQ(negnum.uintval(), static_cast(0xBFFF2) << 108); diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h index e926640abc90e..0744e6ea8fd8f 100644 --- a/libc/test/src/math/FDimTest.h +++ b/libc/test/src/math/FDimTest.h @@ -18,6 +18,13 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test { using FuncPtr = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; + + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); + const T nan = T(FPBits::build_quiet_nan(1)); void test_na_n_arg(FuncPtr func) { EXPECT_FP_EQ(nan, func(nan, inf)); @@ -72,13 +79,4 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test { } } } - -private: - // constexpr does not work on FPBits yet, so we cannot have these constants as - // static. - const T nan = T(FPBits::build_quiet_nan(1)); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); }; diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h index af895e29f33c3..032a79821d590 100644 --- a/libc/test/src/math/FmaTest.h +++ b/libc/test/src/math/FmaTest.h @@ -23,11 +23,13 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test { using Func = T (*)(T, T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; + + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); StorageType get_random_bit_pattern() { StorageType bits{0}; diff --git a/libc/test/src/math/HypotTest.h b/libc/test/src/math/HypotTest.h index 4d8ef86fa9c46..b7eb63c192c70 100644 --- a/libc/test/src/math/HypotTest.h +++ b/libc/test/src/math/HypotTest.h @@ -23,12 +23,13 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using Func = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; + using Sign = LIBC_NAMESPACE::fputil::Sign; using StorageType = typename FPBits::StorageType; const T nan = FPBits::build_quiet_nan(1); const T inf = FPBits::inf(); - const T neg_inf = FPBits::neg_inf(); + const T neg_inf = FPBits::inf(Sign::NEG); const T zero = FPBits::zero(); - const T neg_zero = FPBits::neg_zero(); + const T neg_zero = FPBits::zero(Sign::NEG); const T max_normal = FPBits::max_normal(); const T min_normal = FPBits::min_normal(); const T max_subnormal = FPBits::max_denormal(); diff --git a/libc/test/src/math/ILogbTest.h b/libc/test/src/math/ILogbTest.h index 9f857da5547c7..9fa25c9ff9861 100644 --- a/libc/test/src/math/ILogbTest.h +++ b/libc/test/src/math/ILogbTest.h @@ -25,11 +25,12 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test { template void test_special_numbers(typename ILogbFunc::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits; + using Sign = LIBC_NAMESPACE::fputil::Sign; EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero()))); - EXPECT_EQ(FP_ILOGB0, func(T(FPBits::neg_zero()))); + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::NEG)))); EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan(1)))); EXPECT_EQ(INT_MAX, func(T(FPBits::inf()))); - EXPECT_EQ(INT_MAX, func(T(FPBits::neg_inf()))); + EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::NEG)))); } template diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h index 371654e69c3d5..b507bb4ec56e5 100644 --- a/libc/test/src/math/LdExpTest.h +++ b/libc/test/src/math/LdExpTest.h @@ -23,15 +23,17 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat; using StorageType = typename FPBits::StorageType; - // A normalized mantissa to be used with tests. - static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); + // A normalized mantissa to be used with tests. + static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234; + public: typedef T (*LdExpFunc)(T, int); diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h index 005c5730e8f52..aa9646fd921f8 100644 --- a/libc/test/src/math/NextAfterTest.h +++ b/libc/test/src/math/NextAfterTest.h @@ -21,12 +21,14 @@ template class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); + const StorageType min_subnormal = FPBits::MIN_SUBNORMAL; const StorageType max_subnormal = FPBits::MAX_SUBNORMAL; const StorageType min_normal = FPBits::MIN_NORMAL; diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h index 2471b831759fe..6816e94d389f4 100644 --- a/libc/test/src/math/RIntTest.h +++ b/libc/test/src/math/RIntTest.h @@ -32,11 +32,12 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); static inline mpfr::RoundingMode to_mpfr_rounding_mode(int mode) { diff --git a/libc/test/src/math/RemQuoTest.h b/libc/test/src/math/RemQuoTest.h index 6495b61331dbb..9ed9525662452 100644 --- a/libc/test/src/math/RemQuoTest.h +++ b/libc/test/src/math/RemQuoTest.h @@ -22,11 +22,12 @@ template class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); public: diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h index d76b5a10dfa25..e8ada1b4c36c5 100644 --- a/libc/test/src/math/RoundToIntegerTest.h +++ b/libc/test/src/math/RoundToIntegerTest.h @@ -31,11 +31,12 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; const F zero = F(FPBits::zero()); - const F neg_zero = F(FPBits::neg_zero()); + const F neg_zero = F(FPBits::zero(Sign::NEG)); const F inf = F(FPBits::inf()); - const F neg_inf = F(FPBits::neg_inf()); + const F neg_inf = F(FPBits::inf(Sign::NEG)); const F nan = F(FPBits::build_quiet_nan(1)); static constexpr I INTEGER_MIN = I(1) << (sizeof(I) * 8 - 1); static constexpr I INTEGER_MAX = -(INTEGER_MIN + 1); @@ -127,7 +128,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test { // is set. FPBits bits(F(1.0)); bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXP_BIAS); - bits.set_sign(1); + bits.set_sign(Sign::NEG); bits.set_mantissa(0); F x = F(bits); @@ -191,7 +192,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test { // is set. FPBits bits(F(1.0)); bits.set_biased_exponent(EXPONENT_LIMIT + FPBits::EXP_BIAS); - bits.set_sign(1); + bits.set_sign(Sign::NEG); bits.set_mantissa(FPBits::FRACTION_MASK); F x = F(bits); diff --git a/libc/test/src/math/atanhf_test.cpp b/libc/test/src/math/atanhf_test.cpp index f62830ac9d4ef..fcc9f44dbea93 100644 --- a/libc/test/src/math/atanhf_test.cpp +++ b/libc/test/src/math/atanhf_test.cpp @@ -22,6 +22,7 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest; namespace mpfr = LIBC_NAMESPACE::testing::mpfr; TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { + using Sign = LIBC_NAMESPACE::fputil::Sign; libc_errno = 0; LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(aNaN)); @@ -57,7 +58,7 @@ TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { EXPECT_MATH_ERRNO(EDOM); LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); - bt.set_sign(true); + bt.set_sign(Sign::NEG); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(bt.get_val())); EXPECT_FP_EXCEPTION(FE_INVALID); EXPECT_MATH_ERRNO(EDOM); @@ -77,7 +78,7 @@ TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { EXPECT_FP_EXCEPTION(FE_INVALID); EXPECT_MATH_ERRNO(EDOM); - bt.set_sign(true); + bt.set_sign(Sign::NEG); EXPECT_FP_EQ_ALL_ROUNDING(aNaN, LIBC_NAMESPACE::atanhf(neg_inf)); EXPECT_FP_EXCEPTION(FE_INVALID); EXPECT_MATH_ERRNO(EDOM); diff --git a/libc/test/src/math/smoke/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h index e926640abc90e..0744e6ea8fd8f 100644 --- a/libc/test/src/math/smoke/FDimTest.h +++ b/libc/test/src/math/smoke/FDimTest.h @@ -18,6 +18,13 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test { using FuncPtr = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; + + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); + const T nan = T(FPBits::build_quiet_nan(1)); void test_na_n_arg(FuncPtr func) { EXPECT_FP_EQ(nan, func(nan, inf)); @@ -72,13 +79,4 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test { } } } - -private: - // constexpr does not work on FPBits yet, so we cannot have these constants as - // static. - const T nan = T(FPBits::build_quiet_nan(1)); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); }; diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h index 9dd8dbb534a68..dc624d871b990 100644 --- a/libc/test/src/math/smoke/FmaTest.h +++ b/libc/test/src/math/smoke/FmaTest.h @@ -19,11 +19,13 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test { using Func = T (*)(T, T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; + + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); public: void test_special_numbers(Func func) { diff --git a/libc/test/src/math/smoke/HypotTest.h b/libc/test/src/math/smoke/HypotTest.h index 30200d120ed9d..77454c19a6538 100644 --- a/libc/test/src/math/smoke/HypotTest.h +++ b/libc/test/src/math/smoke/HypotTest.h @@ -21,11 +21,13 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test { using Func = T (*)(T, T); using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; const T nan = FPBits::build_quiet_nan(1); - const T inf = FPBits::inf(); - const T neg_inf = FPBits::neg_inf(); - const T zero = FPBits::zero(); - const T neg_zero = FPBits::neg_zero(); + const T inf = FPBits::inf(Sign::POS); + const T neg_inf = FPBits::inf(Sign::NEG); + const T zero = FPBits::zero(Sign::POS); + const T neg_zero = FPBits::zero(Sign::NEG); + const T max_normal = FPBits::max_normal(); const T min_normal = FPBits::min_normal(); const T max_subnormal = FPBits::max_denormal(); diff --git a/libc/test/src/math/smoke/ILogbTest.h b/libc/test/src/math/smoke/ILogbTest.h index 9f857da5547c7..0a50abc04f727 100644 --- a/libc/test/src/math/smoke/ILogbTest.h +++ b/libc/test/src/math/smoke/ILogbTest.h @@ -25,11 +25,12 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test { template void test_special_numbers(typename ILogbFunc::Func func) { using FPBits = LIBC_NAMESPACE::fputil::FPBits; - EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero()))); - EXPECT_EQ(FP_ILOGB0, func(T(FPBits::neg_zero()))); + using Sign = LIBC_NAMESPACE::fputil::Sign; + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::POS)))); + EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::NEG)))); EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan(1)))); - EXPECT_EQ(INT_MAX, func(T(FPBits::inf()))); - EXPECT_EQ(INT_MAX, func(T(FPBits::neg_inf()))); + EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::POS)))); + EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::NEG)))); } template diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h index 371654e69c3d5..b507bb4ec56e5 100644 --- a/libc/test/src/math/smoke/LdExpTest.h +++ b/libc/test/src/math/smoke/LdExpTest.h @@ -23,15 +23,17 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat; using StorageType = typename FPBits::StorageType; - // A normalized mantissa to be used with tests. - static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); + // A normalized mantissa to be used with tests. + static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234; + public: typedef T (*LdExpFunc)(T, int); diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h index c301f5ebe228e..bdf3da627180a 100644 --- a/libc/test/src/math/smoke/NextAfterTest.h +++ b/libc/test/src/math/smoke/NextAfterTest.h @@ -32,12 +32,14 @@ template class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); + const StorageType min_subnormal = FPBits::MIN_SUBNORMAL; const StorageType max_subnormal = FPBits::MAX_SUBNORMAL; const StorageType min_normal = FPBits::MIN_NORMAL; diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h index 359d4dea0dbc8..af4e0ab14531c 100644 --- a/libc/test/src/math/smoke/NextTowardTest.h +++ b/libc/test/src/math/smoke/NextTowardTest.h @@ -34,15 +34,16 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using ToFPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); const long double to_zero = ToFPBits::zero(); - const long double to_neg_zero = ToFPBits::neg_zero(); + const long double to_neg_zero = ToFPBits::zero(Sign::NEG); const long double to_nan = ToFPBits::build_quiet_nan(1); const StorageType min_subnormal = FPBits::MIN_SUBNORMAL; diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h index 89dc1a59d19d6..b242c7e441b69 100644 --- a/libc/test/src/math/smoke/RIntTest.h +++ b/libc/test/src/math/smoke/RIntTest.h @@ -29,11 +29,12 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); public: diff --git a/libc/test/src/math/smoke/RemQuoTest.h b/libc/test/src/math/smoke/RemQuoTest.h index 4d4a12717f0bb..93e20747e5263 100644 --- a/libc/test/src/math/smoke/RemQuoTest.h +++ b/libc/test/src/math/smoke/RemQuoTest.h @@ -19,11 +19,12 @@ template class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test { using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const T zero = T(FPBits::zero()); - const T neg_zero = T(FPBits::neg_zero()); - const T inf = T(FPBits::inf()); - const T neg_inf = T(FPBits::neg_inf()); + const T inf = T(FPBits::inf(Sign::POS)); + const T neg_inf = T(FPBits::inf(Sign::NEG)); + const T zero = T(FPBits::zero(Sign::POS)); + const T neg_zero = T(FPBits::zero(Sign::NEG)); const T nan = T(FPBits::build_quiet_nan(1)); public: diff --git a/libc/test/src/math/smoke/RoundToIntegerTest.h b/libc/test/src/math/smoke/RoundToIntegerTest.h index cb1ec280518ee..2703b78f00e0f 100644 --- a/libc/test/src/math/smoke/RoundToIntegerTest.h +++ b/libc/test/src/math/smoke/RoundToIntegerTest.h @@ -28,11 +28,12 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test { private: using FPBits = LIBC_NAMESPACE::fputil::FPBits; using StorageType = typename FPBits::StorageType; + using Sign = LIBC_NAMESPACE::fputil::Sign; - const F zero = F(LIBC_NAMESPACE::fputil::FPBits::zero()); - const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits::neg_zero()); - const F inf = F(LIBC_NAMESPACE::fputil::FPBits::inf()); - const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits::neg_inf()); + const F zero = F(LIBC_NAMESPACE::fputil::FPBits::zero(Sign::POS)); + const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits::zero(Sign::NEG)); + const F inf = F(LIBC_NAMESPACE::fputil::FPBits::inf(Sign::POS)); + const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits::inf(Sign::NEG)); const F nan = F(LIBC_NAMESPACE::fputil::FPBits::build_quiet_nan(1)); static constexpr I INTEGER_MIN = I(1) << (sizeof(I) * 8 - 1); static constexpr I INTEGER_MAX = -(INTEGER_MIN + 1); diff --git a/libc/test/src/math/smoke/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp index 0f7dc0d306349..f27b8e130fc91 100644 --- a/libc/test/src/math/smoke/atanhf_test.cpp +++ b/libc/test/src/math/smoke/atanhf_test.cpp @@ -19,6 +19,7 @@ using LlvmLibcAtanhfTest = LIBC_NAMESPACE::testing::FPTest; TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { + using Sign = LIBC_NAMESPACE::fputil::Sign; libc_errno = 0; LIBC_NAMESPACE::fputil::clear_except(FE_ALL_EXCEPT); @@ -50,7 +51,7 @@ TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { FE_INVALID); EXPECT_MATH_ERRNO(EDOM); - bt.set_sign(true); + bt.set_sign(Sign::NEG); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(bt.get_val()), FE_INVALID); EXPECT_MATH_ERRNO(EDOM); @@ -64,7 +65,7 @@ TEST_F(LlvmLibcAtanhfTest, SpecialNumbers) { EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(inf), FE_INVALID); EXPECT_MATH_ERRNO(EDOM); - bt.set_sign(true); + bt.set_sign(Sign::NEG); EXPECT_FP_IS_NAN_WITH_EXCEPTION(LIBC_NAMESPACE::atanhf(neg_inf), FE_INVALID); EXPECT_MATH_ERRNO(EDOM); } diff --git a/libc/test/src/stdlib/strtold_test.cpp b/libc/test/src/stdlib/strtold_test.cpp index 86ac8a6e26d7c..51f9975772aa5 100644 --- a/libc/test/src/stdlib/strtold_test.cpp +++ b/libc/test/src/stdlib/strtold_test.cpp @@ -88,7 +88,7 @@ class LlvmLibcStrToLDTest : public LIBC_NAMESPACE::testing::Test { EXPECT_EQ(str_end - inputString, expectedStrLen); EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval()); - EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign()); + EXPECT_EQ(actual_fp.is_neg(), expected_fp.is_neg()); EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent()); EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa()); EXPECT_EQ(libc_errno, expected_errno); diff --git a/libc/test/src/time/difftime_test.cpp b/libc/test/src/time/difftime_test.cpp index 9c3e8d3f30f2b..68ff4630e61ba 100644 --- a/libc/test/src/time/difftime_test.cpp +++ b/libc/test/src/time/difftime_test.cpp @@ -32,7 +32,7 @@ TEST(LlvmLibcDifftime, SmokeTest) { static_cast(result)); EXPECT_EQ(actual_fp.uintval(), expected_fp.uintval()); - EXPECT_EQ(actual_fp.get_sign(), expected_fp.get_sign()); + EXPECT_EQ(actual_fp.is_neg(), expected_fp.is_neg()); EXPECT_EQ(actual_fp.get_exponent(), expected_fp.get_exponent()); EXPECT_EQ(actual_fp.get_mantissa(), expected_fp.get_mantissa()); }