[libc-commits] [libc] [libc][NFC] Introduce a Sign type for FPBits (PR #78500)
Guillaume Chatelet via libc-commits
libc-commits at lists.llvm.org
Thu Jan 18 02:43:18 PST 2024
https://github.com/gchatelet updated https://github.com/llvm/llvm-project/pull/78500
>From 0e41c24f5f78374e7a2816dc886d338eff3b092b Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Wed, 17 Jan 2024 20:29:47 +0000
Subject: [PATCH 01/10] [libc][NFC] Introduce a Sign type for FPBits
Another patch is needed to cover `DyadicFloat` and `NormalFloat` constructors.
---
libc/src/__support/FPUtil/BasicOperations.h | 12 +-
.../FPUtil/DivisionAndRemainderOperations.h | 6 +-
libc/src/__support/FPUtil/FPBits.h | 118 +++++++++++-------
.../__support/FPUtil/ManipulationFunctions.h | 12 +-
.../FPUtil/NearestIntegerOperations.h | 18 +--
libc/src/__support/FPUtil/NormalFloat.h | 23 ++--
libc/src/__support/FPUtil/dyadic_float.h | 10 +-
libc/src/__support/FPUtil/fpbits_str.h | 6 +-
libc/src/__support/FPUtil/generic/FMA.h | 8 +-
libc/src/__support/FPUtil/generic/FMod.h | 6 +-
libc/src/__support/FPUtil/generic/sqrt.h | 4 +-
.../FPUtil/generic/sqrt_80_bit_long_double.h | 4 +-
libc/src/__support/float_to_string.h | 2 +-
libc/src/__support/str_to_float.h | 16 +--
libc/src/math/generic/acosf.cpp | 3 +-
libc/src/math/generic/asinf.cpp | 3 +-
libc/src/math/generic/atanf.cpp | 10 +-
libc/src/math/generic/atanhf.cpp | 3 +-
libc/src/math/generic/cosf.cpp | 3 +-
libc/src/math/generic/coshf.cpp | 3 +-
libc/src/math/generic/erff.cpp | 2 +-
libc/src/math/generic/exp10f_impl.h | 2 +-
libc/src/math/generic/exp2f_impl.h | 2 +-
libc/src/math/generic/expf.cpp | 2 +-
libc/src/math/generic/expm1.cpp | 11 +-
libc/src/math/generic/expm1f.cpp | 2 +-
libc/src/math/generic/inv_trigf_utils.h | 11 +-
libc/src/math/generic/log.cpp | 2 +-
libc/src/math/generic/log10.cpp | 2 +-
libc/src/math/generic/log10f.cpp | 2 +-
libc/src/math/generic/log1p.cpp | 2 +-
libc/src/math/generic/log1pf.cpp | 2 +-
libc/src/math/generic/log2.cpp | 2 +-
libc/src/math/generic/log2f.cpp | 2 +-
libc/src/math/generic/logf.cpp | 2 +-
libc/src/math/generic/powf.cpp | 26 ++--
libc/src/math/generic/sinf.cpp | 6 +-
libc/src/math/generic/sinhf.cpp | 5 +-
libc/src/math/generic/tanhf.cpp | 11 +-
.../stdio/printf_core/float_dec_converter.h | 22 ++--
.../stdio/printf_core/float_hex_converter.h | 4 +-
.../printf_core/float_inf_nan_converter.h | 4 +-
.../test/src/__support/FPUtil/fpbits_test.cpp | 60 ++++-----
libc/test/src/math/RoundToIntegerTest.h | 5 +-
libc/test/src/math/atanhf_test.cpp | 5 +-
libc/test/src/math/smoke/atanhf_test.cpp | 5 +-
libc/test/src/stdlib/strtold_test.cpp | 2 +-
libc/test/src/time/difftime_test.cpp | 2 +-
48 files changed, 256 insertions(+), 219 deletions(-)
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 2ec61517b0b808..4015edb1b65372 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -20,23 +20,23 @@ namespace fputil {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T abs(T x) {
FPBits<T> bits(x);
- bits.set_sign(0);
+ bits.set_sign(Sign::POS);
return T(bits);
}
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T fmin(T x, T y) {
- FPBits<T> bitx(x), bity(y);
+ const FPBits<T> 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 65bbe6b099dd00..d3401b10a7cab8 100644
--- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
+++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
@@ -43,13 +43,13 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
return x;
}
- bool result_sign = (xbits.get_sign() == ybits.get_sign() ? false : true);
+ bool result_sign = (xbits.is_neg() == ybits.is_neg() ? false : true);
// 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<T> normalx(xbits), normaly(ybits);
int exp = normalx.exponent - normaly.exponent;
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 4309a535abd079..6a94798973e634 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 explicit Sign(bool is_negative)
+ : is_negative(is_negative) {}
+
+ 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:
+ 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<fp_type> {
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<fp_type> {
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<fp_type> {
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 <FPType fp_type> struct FPRep : public FPRepBase<fp_type> {
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<FPType::X86_Binary80> : public FPRepBase<FPType::X86_Binary80> {
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 <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
// 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 <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
// Methods below this are used by tests.
- LIBC_INLINE static constexpr T zero(bool sign = false) {
+ LIBC_INLINE static constexpr T zero(Sign sign = Sign::POS) {
return FPBits(UP::zero(sign)).get_val();
}
- LIBC_INLINE static constexpr T neg_zero() { return zero(true); }
+ LIBC_INLINE static constexpr T neg_zero() { return zero(Sign::NEG); }
- 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 neg_inf() { return inf(Sign::NEG); }
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<T>
- create_value(bool sign, StorageType biased_exp, StorageType mantissa) {
+ create_value(Sign sign, StorageType biased_exp, StorageType mantissa) {
static_assert(get_fp_type<T>() != 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 42433b9b8442db..e0bd251883e20b 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<T>::neg_zero()) : T(FPBits<T>::zero());
+ return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
} 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<T>::neg_zero()) : T(FPBits<T>::zero());
+ return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
} else {
return x - iptr;
}
@@ -65,7 +65,7 @@ LIBC_INLINE T modf(T x, T &iptr) {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T copysign(T x, T y) {
FPBits<T> xbits(x);
- xbits.set_sign(FPBits<T>(y).get_sign());
+ xbits.set_sign(FPBits<T>(y).sign());
return T(xbits);
}
@@ -131,11 +131,11 @@ LIBC_INLINE T ldexp(T x, int exp) {
// calculating the limit.
int exp_limit = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
if (exp > exp_limit)
- return bits.get_sign() ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
+ return bits.is_neg() ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
// Similarly on the negative side we return zero early if |exp| is too small.
if (exp < -exp_limit)
- return bits.get_sign() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
// For all other values, NormalFloat to T conversion handles it the right way.
NormalFloat<T> normal(bits);
@@ -173,7 +173,7 @@ LIBC_INLINE T nextafter(T from, U to) {
}
} else {
int_val = FPBits<T>::MIN_SUBNORMAL;
- if (to_bits.get_sign())
+ if (to_bits.is_neg())
int_val |= FPBits<T>::SIGN_MASK;
}
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index 64c44e0b3a0c44..e32b4d27a7a1df 100644
--- a/libc/src/__support/FPUtil/NearestIntegerOperations.h
+++ b/libc/src/__support/FPUtil/NearestIntegerOperations.h
@@ -41,7 +41,7 @@ LIBC_INLINE T trunc(T x) {
// If the exponent is such that abs(x) is less than 1, then return 0.
if (exponent <= -1) {
- if (bits.get_sign())
+ if (bits.is_neg())
return T(-0.0);
else
return T(0.0);
@@ -60,7 +60,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 +93,7 @@ LIBC_INLINE T ceil(T x) {
template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
LIBC_INLINE T floor(T x) {
FPBits<T> bits(x);
- if (bits.get_sign()) {
+ if (bits.is_neg()) {
return -ceil(-x);
} else {
return trunc(x);
@@ -109,7 +109,7 @@ LIBC_INLINE T round(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
@@ -161,7 +161,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 +247,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_neg() == 0 || 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 e70c89a7dbe15a..39376bfcba0319 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -44,10 +44,10 @@ template <typename T> struct NormalFloat {
static_assert(sizeof(StorageType) * 8 >= FPBits<T>::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(Sign(s)) {
if (mantissa >= ONE)
return;
@@ -64,20 +64,21 @@ template <typename T> 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<T> &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 <typename T> struct NormalFloat {
// Max exponent is of the form 0xFF...E. That is why -2 and not -1.
constexpr int MAX_EXPONENT_VALUE = (1 << FPBits<T>::EXP_LEN) - 2;
if (biased_exponent > MAX_EXPONENT_VALUE) {
- return sign ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
+ return T(FPBits<T>::inf(sign));
}
FPBits<T> result(T(0.0));
@@ -141,7 +142,7 @@ template <typename T> struct NormalFloat {
private:
LIBC_INLINE void init_from_bits(FPBits<T> 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 <typename T> struct NormalFloat {
template <>
LIBC_INLINE void
NormalFloat<long double>::init_from_bits(FPBits<long double> 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<long double>::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<long double> result(0.0l);
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index ccd3c69bf3db2a..3cc3890b65a01b 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 <size_t Bits> struct DyadicFloat {
using MantissaType = LIBC_NAMESPACE::cpp::UInt<Bits>;
- bool sign = false;
+ Sign sign = Sign::POS;
int exponent = 0;
MantissaType mantissa = MantissaType(0);
@@ -43,14 +43,14 @@ template <size_t Bits> struct DyadicFloat {
DyadicFloat(T x) {
static_assert(FPBits<T>::FRACTION_LEN < Bits);
FPBits<T> x_bits(x);
- sign = x_bits.get_sign();
+ sign = x_bits.sign();
exponent = x_bits.get_exponent() - FPBits<T>::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(Sign(s)), exponent(e), mantissa(m) {
normalize();
}
@@ -172,7 +172,7 @@ template <size_t Bits> struct DyadicFloat {
new_mant >>= (-exponent);
}
- if (sign) {
+ if (sign.is_neg()) {
new_mant = (~new_mant) + 1;
}
@@ -251,7 +251,7 @@ template <size_t Bits>
constexpr DyadicFloat<Bits> quick_mul(DyadicFloat<Bits> a,
DyadicFloat<Bits> b) {
DyadicFloat<Bits> 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 50019f32b2c446..b48def8b1cdcf4 100644
--- a/libc/src/__support/FPUtil/fpbits_str.h
+++ b/libc/src/__support/FPUtil/fpbits_str.h
@@ -39,9 +39,9 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
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 = [](bool is_neg) -> char { return is_neg ? '1' : '0'; };
cpp::string s;
@@ -49,7 +49,7 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
s += bits.view();
s += " = (S: ";
- s += sign_char(x.get_sign());
+ s += sign_char(x.is_neg());
s += ", E: ";
const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index b88089ee679f28..db1cc0a4716f74 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>(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,9 +118,9 @@ template <> LIBC_INLINE double fma<double>(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 x_sign = x_bits.is_neg();
+ bool y_sign = y_bits.is_neg();
+ bool z_sign = z_bits.is_neg();
bool prod_sign = x_sign != y_sign;
x_exp += x_bits.get_biased_exponent();
y_exp += y_bits.get_biased_exponent();
diff --git a/libc/src/__support/FPUtil/generic/FMod.h b/libc/src/__support/FPUtil/generic/FMod.h
index d12be7bb14d07a..f4000b97751efc 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 7d56462a168564..f273b678edf527 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<cpp::is_floating_point_v<T>, T> sqrt(T x) {
FPBits<T> 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<T>::build_quiet_nan(ONE >> 1);
} else {
@@ -89,7 +89,7 @@ LIBC_INLINE cpp::enable_if_t<cpp::is_floating_point_v<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<T>::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 8815a18cfbc393..4fe9b49ff41cf0 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<long double> 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 52442608798a5f..f0d712f06e637f 100644
--- a/libc/src/__support/float_to_string.h
+++ b/libc/src/__support/float_to_string.h
@@ -421,7 +421,7 @@ class FloatToString {
public:
LIBC_INLINE constexpr FloatToString(T init_float) : float_bits(init_float) {
- is_negative = float_bits.get_sign();
+ is_negative = float_bits.is_neg();
exponent = float_bits.get_explicit_exponent();
mantissa = float_bits.get_explicit_mantissa();
diff --git a/libc/src/__support/str_to_float.h b/libc/src/__support/str_to_float.h
index f2d4ec7fb11f8b..dd7dfc730ea2cc 100644
--- a/libc/src/__support/str_to_float.h
+++ b/libc/src/__support/str_to_float.h
@@ -1072,6 +1072,7 @@ template <class T>
LIBC_INLINE StrToNumResult<T> strtofloatingpoint(const char *__restrict src) {
using FPBits = typename fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
+ using Sign = fputil::Sign;
FPBits result = FPBits();
bool seen_digit = false;
@@ -1087,7 +1088,7 @@ LIBC_INLINE StrToNumResult<T> 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<T> 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 2a9b2a6852fe9e..67832596a67fba 100644
--- a/libc/src/math/generic/acosf.cpp
+++ b/libc/src/math/generic/acosf.cpp
@@ -38,6 +38,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ACOSF_EXCEPTS = {{
LLVM_LIBC_FUNCTION(float, acosf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
+ 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<double>(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 51eefe984b6779..bc0d27c1eebc5d 100644
--- a/libc/src/math/generic/asinf.cpp
+++ b/libc/src/math/generic/asinf.cpp
@@ -44,6 +44,7 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> ASINF_EXCEPTS_HI = {{
LLVM_LIBC_FUNCTION(float, asinf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
+ 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<double>(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 f2e4f8bb93b6f9..e0f8a1bfc2ecc9 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<float>;
+ 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<float>(opt_barrier(sign ? -M_MATH_PI_2 : M_MATH_PI_2));
+ return static_cast<float>(
+ 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 df5f53f392cf30..fd6f5c96b6b4e6 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<float>;
+ 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 67b60de03024fb..89333ab19e89f9 100644
--- a/libc/src/math/generic/cosf.cpp
+++ b/libc/src/math/generic/cosf.cpp
@@ -42,8 +42,9 @@ static constexpr fputil::ExceptValues<float, N_EXCEPTS> COSF_EXCEPTS{{
LLVM_LIBC_FUNCTION(float, cosf, (float x)) {
using FPBits = typename fputil::FPBits<float>;
+ 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<double>(xbits.get_val());
diff --git a/libc/src/math/generic/coshf.cpp b/libc/src/math/generic/coshf.cpp
index 4a55b6940ff8c2..3b01852e9f544a 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<float>;
+ 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 333ca197dbedb5..f120d5646e0439 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<int>(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 a2ec5391ba50a7..2861659a6e57e0 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 e6fd65264c721e..86360840b96e6f 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 d0bb681df9e9dd..88d408994fe427 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 8ab341d55a226e..3d343a99d1c288 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<double>;
+ 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,7 @@ 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<uint64_t>(-hi) << 52) : 0;
+ uint64_t err = x_is_neg ? (static_cast<uint64_t>(-hi) << 52) : 0;
double err_d = cpp::bit_cast<double>(ERR_D + err);
diff --git a/libc/src/math/generic/expm1f.cpp b/libc/src/math/generic/expm1f.cpp
index 3739a7bbbaa84c..c6e0663ec46c3f 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 4e85d4ae08d571..20f912de2ac008 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<double>;
+ 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 8f22fdea93217f..859b32ddb77c41 100644
--- a/libc/src/math/generic/log.cpp
+++ b/libc/src/math/generic/log.cpp
@@ -749,7 +749,7 @@ LLVM_LIBC_FUNCTION(double, log, (double x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
}
- 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 df82f24dc6967c..12a51b7182e6a2 100644
--- a/libc/src/math/generic/log10.cpp
+++ b/libc/src/math/generic/log10.cpp
@@ -750,7 +750,7 @@ LLVM_LIBC_FUNCTION(double, log10, (double x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
}
- 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 da69f7f5ad4d9e..40122391d1b6b4 100644
--- a/libc/src/math/generic/log10f.cpp
+++ b/libc/src/math/generic/log10f.cpp
@@ -167,7 +167,7 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
}
- 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 74eed6ceeb28dc..caa8b2e4d0b4cc 100644
--- a/libc/src/math/generic/log1p.cpp
+++ b/libc/src/math/generic/log1p.cpp
@@ -894,7 +894,7 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
}
- 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 891700d5ed08c8..eadb3435abb975 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<float>::build_quiet_nan(0);
diff --git a/libc/src/math/generic/log2.cpp b/libc/src/math/generic/log2.cpp
index 1427d1934db900..5ef2d100bf758b 100644
--- a/libc/src/math/generic/log2.cpp
+++ b/libc/src/math/generic/log2.cpp
@@ -871,7 +871,7 @@ LLVM_LIBC_FUNCTION(double, log2, (double x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
}
- 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 07dedba85e6273..4bd40522ce2dac 100644
--- a/libc/src/math/generic/log2f.cpp
+++ b/libc/src/math/generic/log2f.cpp
@@ -74,7 +74,7 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
}
- 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 f1f93468479b11..358994735929a1 100644
--- a/libc/src/math/generic/logf.cpp
+++ b/libc/src/math/generic/logf.cpp
@@ -119,7 +119,7 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
}
- 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 49f33b71c56009..f1be147298a410 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<double>;
+ 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<uint64_t>(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<float>;
using DoubleBits = typename fputil::FPBits<double>;
+ 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(Sign(out_is_neg));
}
// 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(Sign(out_is_neg));
}
}
@@ -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 6fc1abb83e2e7b..9e574d4e572402 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 d64519d0ec79bf..b3850c67427066 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 48e78ec2383f29..0efd0cefebe577 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<int>(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<int>(
- 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<double>(-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 cfa351cf017aeb..e1a44234bb309f 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<T> float_bits) {
// signed because later we use -FRACTION_LEN
constexpr int32_t FRACTION_LEN = fputil::FPBits<T>::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,8 @@ 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 +587,6 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer,
fputil::FPBits<T> float_bits) {
// signed because later we use -FRACTION_LEN
constexpr int32_t FRACTION_LEN = fputil::FPBits<T>::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 +594,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 +734,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 +749,6 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer,
fputil::FPBits<T> float_bits) {
// signed because later we use -FRACTION_LEN
constexpr int32_t FRACTION_LEN = fputil::FPBits<T>::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 +981,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 5ccae81b430c57..68a4ba6209d091 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<LBits::StorageType>(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 8669dc374cb297..f755ef6e31f261 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<long double>::StorageType float_raw = to_conv.conv_val_raw;
fputil::FPBits<long double> float_bits(float_raw);
- is_negative = float_bits.get_sign();
+ is_negative = float_bits.is_neg();
mantissa = float_bits.get_mantissa();
} else {
fputil::FPBits<double>::StorageType float_raw =
static_cast<fputil::FPBits<double>::StorageType>(to_conv.conv_val_raw);
fputil::FPBits<double> 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/src/__support/FPUtil/fpbits_test.cpp b/libc/test/src/__support/FPUtil/fpbits_test.cpp
index a955f460cf3bb3..c2ddb8070508df 100644
--- a/libc/test/src/__support/FPUtil/fpbits_test.cpp
+++ b/libc/test/src/__support/FPUtil/fpbits_test.cpp
@@ -236,7 +236,7 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
"(NaN)");
FloatBits zero(0.0f);
- EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_TRUE(zero.is_pos());
EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0));
EXPECT_EQ(zero.get_mantissa(), static_cast<uint32_t>(0));
EXPECT_EQ(zero.uintval(), static_cast<uint32_t>(0x00000000));
@@ -244,7 +244,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<uint16_t>(0));
EXPECT_EQ(negzero.get_mantissa(), static_cast<uint32_t>(0));
EXPECT_EQ(negzero.uintval(), static_cast<uint32_t>(0x80000000));
@@ -252,7 +252,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<uint16_t>(0x7F));
EXPECT_EQ(one.get_mantissa(), static_cast<uint32_t>(0));
EXPECT_EQ(one.uintval(), static_cast<uint32_t>(0x3F800000));
@@ -260,7 +260,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<uint16_t>(0x7F));
EXPECT_EQ(negone.get_mantissa(), static_cast<uint32_t>(0));
EXPECT_EQ(negone.uintval(), static_cast<uint32_t>(0xBF800000));
@@ -268,7 +268,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<uint16_t>(0x7F));
EXPECT_EQ(num.get_mantissa(), static_cast<uint32_t>(0x00100000));
EXPECT_EQ(num.uintval(), static_cast<uint32_t>(0x3F900000));
@@ -276,7 +276,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<uint16_t>(0x7F));
EXPECT_EQ(negnum.get_mantissa(), static_cast<uint32_t>(0x00100000));
EXPECT_EQ(negnum.uintval(), static_cast<uint32_t>(0xBF900000));
@@ -299,7 +299,7 @@ TEST(LlvmLibcFPBitsTest, DoubleType) {
"(NaN)");
DoubleBits zero(0.0);
- EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_TRUE(zero.is_pos());
EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
EXPECT_EQ(zero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
EXPECT_EQ(zero.uintval(), static_cast<uint64_t>(0x0000000000000000));
@@ -307,7 +307,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<uint16_t>(0x0000));
EXPECT_EQ(negzero.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
EXPECT_EQ(negzero.uintval(), static_cast<uint64_t>(0x8000000000000000));
@@ -315,7 +315,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<uint16_t>(0x03FF));
EXPECT_EQ(one.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
EXPECT_EQ(one.uintval(), static_cast<uint64_t>(0x3FF0000000000000));
@@ -323,7 +323,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<uint16_t>(0x03FF));
EXPECT_EQ(negone.get_mantissa(), static_cast<uint64_t>(0x0000000000000000));
EXPECT_EQ(negone.uintval(), static_cast<uint64_t>(0xBFF0000000000000));
@@ -331,7 +331,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<uint16_t>(0x03FF));
EXPECT_EQ(num.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
EXPECT_EQ(num.uintval(), static_cast<uint64_t>(0x3FF2000000000000));
@@ -339,7 +339,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<uint16_t>(0x03FF));
EXPECT_EQ(negnum.get_mantissa(), static_cast<uint64_t>(0x0002000000000000));
EXPECT_EQ(negnum.uintval(), static_cast<uint64_t>(0xBFF2000000000000));
@@ -368,7 +368,7 @@ TEST(LlvmLibcFPBitsTest, X86LongDoubleType) {
"(NaN)");
LongDoubleBits zero(0.0l);
- EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_TRUE(zero.is_pos());
EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -379,7 +379,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<uint16_t>(0x0000));
EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -390,7 +390,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<uint16_t>(0x3FFF));
EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF8) << 60);
@@ -400,7 +400,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<uint16_t>(0x3FFF));
EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -411,7 +411,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<uint16_t>(0x3FFF));
EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x1) << 60);
EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF9) << 60);
@@ -421,7 +421,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<uint16_t>(0x3FFF));
EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x1) << 60);
EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF9) << 60);
@@ -451,7 +451,7 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
"(NaN)");
LongDoubleBits zero(0.0l);
- EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_TRUE(zero.is_pos());
EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -461,7 +461,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<uint16_t>(0x0000));
EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -471,7 +471,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<uint16_t>(0x3FFF));
EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF) << 112);
@@ -480,7 +480,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<uint16_t>(0x3FFF));
EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -490,7 +490,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<uint16_t>(0x3FFF));
EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x2) << 108);
EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF2) << 108);
@@ -499,7 +499,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<uint16_t>(0x3FFF));
EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x2) << 108);
EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF2) << 108);
@@ -527,7 +527,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
"(NaN)");
Float128Bits zero(Float128Bits::zero());
- EXPECT_EQ(zero.get_sign(), false);
+ EXPECT_TRUE(zero.is_pos());
EXPECT_EQ(zero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
EXPECT_EQ(zero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -537,7 +537,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
"(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)");
Float128Bits negzero(Float128Bits::neg_zero());
- EXPECT_EQ(negzero.get_sign(), true);
+ EXPECT_TRUE(negzero.is_neg());
EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -547,7 +547,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<uint16_t>(0x3FFF));
EXPECT_EQ(one.get_mantissa(), static_cast<UInt128>(0x0000000000000000) << 64);
EXPECT_EQ(one.uintval(), static_cast<UInt128>(0x3FFF) << 112);
@@ -556,7 +556,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<uint16_t>(0x3FFF));
EXPECT_EQ(negone.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
<< 64);
@@ -566,7 +566,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<uint16_t>(0x3FFF));
EXPECT_EQ(num.get_mantissa(), static_cast<UInt128>(0x2) << 108);
EXPECT_EQ(num.uintval(), static_cast<UInt128>(0x3FFF2) << 108);
@@ -575,7 +575,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<uint16_t>(0x3FFF));
EXPECT_EQ(negnum.get_mantissa(), static_cast<UInt128>(0x2) << 108);
EXPECT_EQ(negnum.uintval(), static_cast<UInt128>(0xBFFF2) << 108);
diff --git a/libc/test/src/math/RoundToIntegerTest.h b/libc/test/src/math/RoundToIntegerTest.h
index d76b5a10dfa259..b8f1c85cb91c2e 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -31,6 +31,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
private:
using FPBits = LIBC_NAMESPACE::fputil::FPBits<F>;
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());
@@ -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 f62830ac9d4ef7..fcc9f44dbea932 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<float>;
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/atanhf_test.cpp b/libc/test/src/math/smoke/atanhf_test.cpp
index 0f7dc0d3063490..f27b8e130fc919 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<float>;
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 86ac8a6e26d7c0..51f9975772aa5e 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 9c3e8d3f30f2b9..68ff4630e61baf 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<long double>(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());
}
>From 1ddf1c20edfd7a58dd03921df4bc49aedc1fe7c8 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Wed, 17 Jan 2024 20:50:47 +0000
Subject: [PATCH 02/10] Simplify some expressions
---
libc/src/__support/FPUtil/FPBits.h | 5 ++++
.../__support/FPUtil/ManipulationFunctions.h | 4 ++--
.../FPUtil/NearestIntegerOperations.h | 23 +++++--------------
3 files changed, 13 insertions(+), 19 deletions(-)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 6a94798973e634..75ce2c699a488a 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -708,6 +708,11 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
// Methods below this are used by tests.
+
+ LIBC_INLINE static constexpr T one(Sign sign = Sign::POS) {
+ return FPBits(UP::one(sign)).get_val();
+ }
+
LIBC_INLINE static constexpr T zero(Sign sign = Sign::POS) {
return FPBits(UP::zero(sign)).get_val();
}
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index e0bd251883e20b..a162ce5fbf6fa0 100644
--- a/libc/src/__support/FPUtil/ManipulationFunctions.h
+++ b/libc/src/__support/FPUtil/ManipulationFunctions.h
@@ -131,11 +131,11 @@ LIBC_INLINE T ldexp(T x, int exp) {
// calculating the limit.
int exp_limit = FPBits<T>::MAX_BIASED_EXPONENT + FPBits<T>::FRACTION_LEN + 1;
if (exp > exp_limit)
- return bits.is_neg() ? T(FPBits<T>::neg_inf()) : T(FPBits<T>::inf());
+ return T(FPBits<T>::inf(bits.sign()));
// Similarly on the negative side we return zero early if |exp| is too small.
if (exp < -exp_limit)
- return bits.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return T(FPBits<T>::zero(bits.sign()));
// For all other values, NormalFloat to T conversion handles it the right way.
NormalFloat<T> normal(bits);
diff --git a/libc/src/__support/FPUtil/NearestIntegerOperations.h b/libc/src/__support/FPUtil/NearestIntegerOperations.h
index e32b4d27a7a1df..62568977dc0c8b 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.is_neg())
- return T(-0.0);
- else
- return T(0.0);
- }
+ if (exponent <= -1)
+ return T(FPBits<T>::zero(bits.sign()));
int trim_size = FPBits<T>::FRACTION_LEN - exponent;
bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
@@ -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.is_neg();
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<T>::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<T>::zero(bits.sign()));
}
uint32_t trim_size = FPBits<T>::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);
}
}
@@ -256,7 +245,7 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) {
set_domain_error_and_raise_invalid();
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
} else if (exponent == EXPONENT_LIMIT) {
- if (bits.is_neg() == 0 || bits.get_mantissa() != 0) {
+ if (bits.is_pos() || bits.get_mantissa() != 0) {
set_domain_error_and_raise_invalid();
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
}
>From 822fe22e7b1a527718feac7862d386eda43bdd9e Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Wed, 17 Jan 2024 21:01:16 +0000
Subject: [PATCH 03/10] More simplifications
---
libc/src/__support/FPUtil/generic/FMA.h | 25 +++++++++++--------------
libc/src/__support/float_to_string.h | 4 ----
2 files changed, 11 insertions(+), 18 deletions(-)
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index db1cc0a4716f74..2aaf6ce369a37a 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -118,10 +118,8 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
}
FPBits x_bits(x), y_bits(y), z_bits(z);
- bool x_sign = x_bits.is_neg();
- bool y_sign = y_bits.is_neg();
- bool z_sign = z_bits.is_neg();
- bool prod_sign = x_sign != y_sign;
+ const Sign z_sign = z_bits.sign();
+ Sign prod_sign = Sign(x_bits.sign() != y_bits.sign());
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>(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<double>(result)
- : cpp::bit_cast<double>(result);
+ return prod_sign.is_neg() ? -cpp::bit_cast<double>(result)
+ : cpp::bit_cast<double>(result);
}
- return prod_sign ? static_cast<double>(FPBits::neg_inf())
- : static_cast<double>(FPBits::inf());
+ return static_cast<double>(FPBits::inf(prod_sign));
}
// Remove hidden bit and append the exponent field and sign bit.
result = (result & FPBits::FRACTION_MASK) |
(static_cast<uint64_t>(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>(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/float_to_string.h b/libc/src/__support/float_to_string.h
index f0d712f06e637f..ab1afbe54dfac0 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 <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T>, int> = 0>
class FloatToString {
fputil::FPBits<T> 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.is_neg();
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(); }
>From e75bfc699fb28dcb9c16f3b7988eb89229f44827 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Wed, 17 Jan 2024 21:25:56 +0000
Subject: [PATCH 04/10] Remove neg_zero / neg_inf
---
libc/src/__support/FPUtil/FPBits.h | 5 ---
.../__support/FPUtil/ManipulationFunctions.h | 8 ++--
libc/src/math/generic/log.cpp | 2 +-
libc/src/math/generic/log10.cpp | 2 +-
libc/src/math/generic/log10f.cpp | 2 +-
libc/src/math/generic/log1p.cpp | 2 +-
libc/src/math/generic/log1pf.cpp | 2 +-
libc/src/math/generic/log2.cpp | 2 +-
libc/src/math/generic/log2f.cpp | 2 +-
libc/src/math/generic/logf.cpp | 4 +-
libc/test/UnitTest/FPMatcher.h | 18 ++++----
.../test/src/__support/FPUtil/fpbits_test.cpp | 42 ++++++++++++-------
libc/test/src/math/FDimTest.h | 5 ++-
libc/test/src/math/FmaTest.h | 4 +-
libc/test/src/math/HypotTest.h | 5 ++-
libc/test/src/math/ILogbTest.h | 5 ++-
libc/test/src/math/LdExpTest.h | 5 ++-
libc/test/src/math/NextAfterTest.h | 5 ++-
libc/test/src/math/RIntTest.h | 5 ++-
libc/test/src/math/RemQuoTest.h | 5 ++-
libc/test/src/math/RoundToIntegerTest.h | 4 +-
libc/test/src/math/smoke/FDimTest.h | 4 +-
libc/test/src/math/smoke/FmaTest.h | 4 +-
libc/test/src/math/smoke/HypotTest.h | 4 +-
libc/test/src/math/smoke/ILogbTest.h | 4 +-
libc/test/src/math/smoke/LdExpTest.h | 4 +-
libc/test/src/math/smoke/NextAfterTest.h | 4 +-
libc/test/src/math/smoke/NextTowardTest.h | 6 +--
libc/test/src/math/smoke/RIntTest.h | 4 +-
libc/test/src/math/smoke/RemQuoTest.h | 4 +-
libc/test/src/math/smoke/RoundToIntegerTest.h | 2 +-
31 files changed, 94 insertions(+), 80 deletions(-)
diff --git a/libc/src/__support/FPUtil/FPBits.h b/libc/src/__support/FPUtil/FPBits.h
index 75ce2c699a488a..990b88d18efeef 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -708,7 +708,6 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
// Methods below this are used by tests.
-
LIBC_INLINE static constexpr T one(Sign sign = Sign::POS) {
return FPBits(UP::one(sign)).get_val();
}
@@ -717,14 +716,10 @@ template <typename T> struct FPBits : public internal::FPRep<get_fp_type<T>()> {
return FPBits(UP::zero(sign)).get_val();
}
- LIBC_INLINE static constexpr T neg_zero() { return zero(Sign::NEG); }
-
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(Sign::NEG); }
-
LIBC_INLINE static constexpr T min_normal() {
return FPBits(UP::min_normal(Sign::POS)).get_val();
}
diff --git a/libc/src/__support/FPUtil/ManipulationFunctions.h b/libc/src/__support/FPUtil/ManipulationFunctions.h
index a162ce5fbf6fa0..81c8281f3c7bbe 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.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return T(FPBits<T>::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.is_neg() ? T(FPBits<T>::neg_zero()) : T(FPBits<T>::zero());
+ return T(FPBits<T>::zero(bits.sign()));
} else {
return x - iptr;
}
@@ -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<T>::neg_inf());
+ return T(FPBits<T>::inf(Sign::NEG));
} else if (bits.is_nan()) {
return x;
} else if (bits.is_inf()) {
// Return positive infinity.
- return T(FPBits<T>::inf());
+ return T(FPBits<T>::inf(Sign::POS));
}
NormalFloat<T> normal(bits);
diff --git a/libc/src/math/generic/log.cpp b/libc/src/math/generic/log.cpp
index 859b32ddb77c41..5b3f48c85614b7 100644
--- a/libc/src/math/generic/log.cpp
+++ b/libc/src/math/generic/log.cpp
@@ -747,7 +747,7 @@ 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<double>(FPBits_t::neg_inf());
+ return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/log10.cpp b/libc/src/math/generic/log10.cpp
index 12a51b7182e6a2..b7b49e2b3ac4b1 100644
--- a/libc/src/math/generic/log10.cpp
+++ b/libc/src/math/generic/log10.cpp
@@ -748,7 +748,7 @@ 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<double>(FPBits_t::neg_inf());
+ return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/log10f.cpp b/libc/src/math/generic/log10f.cpp
index 40122391d1b6b4..46505f4e07e676 100644
--- a/libc/src/math/generic/log10f.cpp
+++ b/libc/src/math/generic/log10f.cpp
@@ -165,7 +165,7 @@ 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<float>(FPBits::neg_inf());
+ return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
// Return NaN and raise FE_INVALID
diff --git a/libc/src/math/generic/log1p.cpp b/libc/src/math/generic/log1p.cpp
index caa8b2e4d0b4cc..af651d3e5bca27 100644
--- a/libc/src/math/generic/log1p.cpp
+++ b/libc/src/math/generic/log1p.cpp
@@ -892,7 +892,7 @@ 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<double>(FPBits_t::neg_inf());
+ return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
// x < -1.0
diff --git a/libc/src/math/generic/log1pf.cpp b/libc/src/math/generic/log1pf.cpp
index eadb3435abb975..0812569c624b85 100644
--- a/libc/src/math/generic/log1pf.cpp
+++ b/libc/src/math/generic/log1pf.cpp
@@ -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<float>(fputil::FPBits<float>::neg_inf());
+ return static_cast<float>(fputil::FPBits<float>::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 5ef2d100bf758b..261078f7107426 100644
--- a/libc/src/math/generic/log2.cpp
+++ b/libc/src/math/generic/log2.cpp
@@ -869,7 +869,7 @@ 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<double>(FPBits_t::neg_inf());
+ return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/log2f.cpp b/libc/src/math/generic/log2f.cpp
index 4bd40522ce2dac..9cddbb9e8ea486 100644
--- a/libc/src/math/generic/log2f.cpp
+++ b/libc/src/math/generic/log2f.cpp
@@ -72,7 +72,7 @@ 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<float>(FPBits::neg_inf());
+ return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
diff --git a/libc/src/math/generic/logf.cpp b/libc/src/math/generic/logf.cpp
index 358994735929a1..8ccb55dcc9e336 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<float>(FPBits::neg_inf());
+ return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
// Normalize denormal inputs.
xbits = FPBits(xbits.get_val() * 0x1.0p23f);
@@ -117,7 +117,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<float>(FPBits::neg_inf());
+ return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
if (xbits.is_neg() && !xbits.is_nan()) {
// Return NaN and raise FE_INVALID
diff --git a/libc/test/UnitTest/FPMatcher.h b/libc/test/UnitTest/FPMatcher.h
index 003de7eb72ac8e..26b8e3e60bdfd6 100644
--- a/libc/test/UnitTest/FPMatcher.h
+++ b/libc/test/UnitTest/FPMatcher.h
@@ -63,14 +63,15 @@ template <TestCond C, typename T> FPMatcher<T, C> getMatcher(T expectedValue) {
template <typename T> struct FPTest : public Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
static constexpr StorageType STORAGE_MAX =
LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::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 <typename T> struct FPTest : public Test {
#define DECLARE_SPECIAL_CONSTANTS(T) \
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>; \
using StorageType = typename FPBits::StorageType; \
+ using Sign = LIBC_NAMESPACE::fputil::Sign; \
static constexpr StorageType STORAGE_MAX = \
LIBC_NAMESPACE::cpp::numeric_limits<StorageType>::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 c2ddb8070508df..f0b155085dabf5 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,10 +229,12 @@ TEST(LlvmLibcFPBitsTest, FPType_IEEE754_Binary128) {
TEST(LlvmLibcFPBitsTest, FloatType) {
using FloatBits = FPBits<float>;
- 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)");
@@ -290,10 +293,12 @@ TEST(LlvmLibcFPBitsTest, FloatType) {
TEST(LlvmLibcFPBitsTest, DoubleType) {
using DoubleBits = FPBits<double>;
- 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)");
@@ -358,10 +363,12 @@ 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(),
@@ -441,10 +448,12 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
using LongDoubleBits = FPBits<long double>;
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(),
@@ -517,10 +526,11 @@ TEST(LlvmLibcFPBitsTest, LongDoubleType) {
TEST(LlvmLibcFPBitsTest, Float128Type) {
using Float128Bits = FPBits<float128>;
- 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(),
@@ -536,7 +546,7 @@ TEST(LlvmLibcFPBitsTest, Float128Type) {
"0x00000000000000000000000000000000 = "
"(S: 0, E: 0x0000, M: 0x00000000000000000000000000000000)");
- Float128Bits negzero(Float128Bits::neg_zero());
+ Float128Bits negzero(Float128Bits::zero(Sign::NEG));
EXPECT_TRUE(negzero.is_neg());
EXPECT_EQ(negzero.get_biased_exponent(), static_cast<uint16_t>(0x0000));
EXPECT_EQ(negzero.get_mantissa(), static_cast<UInt128>(0x0000000000000000)
diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h
index e926640abc90e0..288d966b97ee86 100644
--- a/libc/test/src/math/FDimTest.h
+++ b/libc/test/src/math/FDimTest.h
@@ -17,6 +17,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
public:
using FuncPtr = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
using StorageType = typename FPBits::StorageType;
void test_na_n_arg(FuncPtr func) {
@@ -78,7 +79,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
// 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 neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
};
diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h
index af895e29f33c3e..c528c10401e293 100644
--- a/libc/test/src/math/FmaTest.h
+++ b/libc/test/src/math/FmaTest.h
@@ -25,9 +25,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
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 neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
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 4d8ef86fa9c461..b7eb63c192c70c 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<T>;
+ 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 9f857da5547c7d..9fa25c9ff98614 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 <typename T>
void test_special_numbers(typename ILogbFunc<T>::Func func) {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
+ 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 <typename T>
diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h
index 371654e69c3d54..fe3c492d25f851 100644
--- a/libc/test/src/math/LdExpTest.h
+++ b/libc/test/src/math/LdExpTest.h
@@ -22,14 +22,15 @@ template <typename T>
class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
using StorageType = typename FPBits::StorageType;
// A normalized mantissa to be used with tests.
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));
public:
diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h
index 005c5730e8f52d..62f7d596827531 100644
--- a/libc/test/src/math/NextAfterTest.h
+++ b/libc/test/src/math/NextAfterTest.h
@@ -21,11 +21,12 @@ template <typename T>
class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
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 neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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;
diff --git a/libc/test/src/math/RIntTest.h b/libc/test/src/math/RIntTest.h
index 2471b831759fe7..3a8430dc31b35e 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<T>;
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 neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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 6495b61331dbb5..728db594a56cff 100644
--- a/libc/test/src/math/RemQuoTest.h
+++ b/libc/test/src/math/RemQuoTest.h
@@ -22,11 +22,12 @@ template <typename T>
class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
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 neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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 b8f1c85cb91c2e..e8ada1b4c36c50 100644
--- a/libc/test/src/math/RoundToIntegerTest.h
+++ b/libc/test/src/math/RoundToIntegerTest.h
@@ -34,9 +34,9 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
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);
diff --git a/libc/test/src/math/smoke/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h
index e926640abc90e0..f40dd172e58b6c 100644
--- a/libc/test/src/math/smoke/FDimTest.h
+++ b/libc/test/src/math/smoke/FDimTest.h
@@ -78,7 +78,7 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
// 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 neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
};
diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h
index 9dd8dbb534a68e..d52c220a827f5f 100644
--- a/libc/test/src/math/smoke/FmaTest.h
+++ b/libc/test/src/math/smoke/FmaTest.h
@@ -21,9 +21,9 @@ class FmaTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
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 neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
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 30200d120ed9d8..07e774e1e00a32 100644
--- a/libc/test/src/math/smoke/HypotTest.h
+++ b/libc/test/src/math/smoke/HypotTest.h
@@ -23,9 +23,9 @@ class HypotTestTemplate : public LIBC_NAMESPACE::testing::Test {
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/smoke/ILogbTest.h b/libc/test/src/math/smoke/ILogbTest.h
index 9f857da5547c7d..f6b56305403551 100644
--- a/libc/test/src/math/smoke/ILogbTest.h
+++ b/libc/test/src/math/smoke/ILogbTest.h
@@ -26,10 +26,10 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
void test_special_numbers(typename ILogbFunc<T>::Func func) {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
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 <typename T>
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 371654e69c3d54..9e7ecd83f7b9bb 100644
--- a/libc/test/src/math/smoke/LdExpTest.h
+++ b/libc/test/src/math/smoke/LdExpTest.h
@@ -27,9 +27,9 @@ class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));
public:
diff --git a/libc/test/src/math/smoke/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index c301f5ebe228e1..66f7f587f653bf 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -34,9 +34,9 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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;
diff --git a/libc/test/src/math/smoke/NextTowardTest.h b/libc/test/src/math/smoke/NextTowardTest.h
index 359d4dea0dbc86..1d80a67f25a5ed 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -36,13 +36,13 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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 89dc1a59d19d64..1523f81ae87bf5 100644
--- a/libc/test/src/math/smoke/RIntTest.h
+++ b/libc/test/src/math/smoke/RIntTest.h
@@ -31,9 +31,9 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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 4d4a12717f0bb8..127c1632f80bb7 100644
--- a/libc/test/src/math/smoke/RemQuoTest.h
+++ b/libc/test/src/math/smoke/RemQuoTest.h
@@ -21,9 +21,9 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::neg_zero());
+ const T neg_zero = T(FPBits::zero(Sign::NEG));
const T inf = T(FPBits::inf());
- const T neg_inf = T(FPBits::neg_inf());
+ const T neg_inf = T(FPBits::inf(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 cb1ec280518ee5..2850b06605ce8e 100644
--- a/libc/test/src/math/smoke/RoundToIntegerTest.h
+++ b/libc/test/src/math/smoke/RoundToIntegerTest.h
@@ -30,7 +30,7 @@ class RoundToIntegerTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
const F zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::zero());
- const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::neg_zero());
+ const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::zero(Sign::NEG));
const F inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::inf());
const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::neg_inf());
const F nan = F(LIBC_NAMESPACE::fputil::FPBits<F>::build_quiet_nan(1));
>From 05d638b98caf91d6db6e547c98d0a7a6bec18140 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Wed, 17 Jan 2024 21:46:21 +0000
Subject: [PATCH 05/10] Fix formatting
---
libc/src/stdio/printf_core/float_dec_converter.h | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/libc/src/stdio/printf_core/float_dec_converter.h b/libc/src/stdio/printf_core/float_dec_converter.h
index e1a44234bb309f..6171d1d5946e6a 100644
--- a/libc/src/stdio/printf_core/float_dec_converter.h
+++ b/libc/src/stdio/printf_core/float_dec_converter.h
@@ -566,8 +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, float_bits.sign());
+ round = get_round_direction(last_digit, truncated, float_bits.sign());
RET_IF_RESULT_NEGATIVE(
float_writer.write_last_block(digits, maximum, round));
>From 59cca22f8883f8e216360a1da031afbebb47a48e Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 18 Jan 2024 10:06:59 +0000
Subject: [PATCH 06/10] Fix failing tests
---
libc/test/src/math/FDimTest.h | 17 +++++++----------
libc/test/src/math/FmaTest.h | 8 +++++---
libc/test/src/math/LdExpTest.h | 13 +++++++------
libc/test/src/math/NextAfterTest.h | 7 ++++---
libc/test/src/math/RIntTest.h | 6 +++---
libc/test/src/math/RemQuoTest.h | 6 +++---
libc/test/src/math/smoke/FDimTest.h | 16 +++++++---------
libc/test/src/math/smoke/FmaTest.h | 8 +++++---
libc/test/src/math/smoke/HypotTest.h | 6 ++++--
libc/test/src/math/smoke/ILogbTest.h | 5 +++--
libc/test/src/math/smoke/LdExpTest.h | 12 +++++++-----
libc/test/src/math/smoke/NextAfterTest.h | 8 +++++---
libc/test/src/math/smoke/NextTowardTest.h | 7 ++++---
libc/test/src/math/smoke/RIntTest.h | 7 ++++---
libc/test/src/math/smoke/RemQuoTest.h | 7 ++++---
libc/test/src/math/smoke/RoundToIntegerTest.h | 7 ++++---
16 files changed, 76 insertions(+), 64 deletions(-)
diff --git a/libc/test/src/math/FDimTest.h b/libc/test/src/math/FDimTest.h
index 288d966b97ee86..0744e6ea8fd8fe 100644
--- a/libc/test/src/math/FDimTest.h
+++ b/libc/test/src/math/FDimTest.h
@@ -17,8 +17,14 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
public:
using FuncPtr = T (*)(T, T);
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
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));
@@ -73,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::inf(Sign::NEG));
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
};
diff --git a/libc/test/src/math/FmaTest.h b/libc/test/src/math/FmaTest.h
index c528c10401e293..032a79821d5901 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<T>;
using StorageType = typename FPBits::StorageType;
- const T nan = T(FPBits::build_quiet_nan(1));
- const T inf = T(FPBits::inf());
+ 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());
+ 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));
StorageType get_random_bit_pattern() {
StorageType bits{0};
diff --git a/libc/test/src/math/LdExpTest.h b/libc/test/src/math/LdExpTest.h
index fe3c492d25f851..b507bb4ec56e55 100644
--- a/libc/test/src/math/LdExpTest.h
+++ b/libc/test/src/math/LdExpTest.h
@@ -22,17 +22,18 @@ template <typename T>
class LdExpTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
- using Sign = LIBC_NAMESPACE::fputil::Sign;
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::zero(Sign::NEG));
- const T inf = T(FPBits::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 62f7d596827531..2dc848b3ea36a0 100644
--- a/libc/test/src/math/NextAfterTest.h
+++ b/libc/test/src/math/NextAfterTest.h
@@ -23,11 +23,12 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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 3a8430dc31b35e..6816e94d389f4e 100644
--- a/libc/test/src/math/RIntTest.h
+++ b/libc/test/src/math/RIntTest.h
@@ -34,10 +34,10 @@ class RIntTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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 728db594a56cff..9ed95256624521 100644
--- a/libc/test/src/math/RemQuoTest.h
+++ b/libc/test/src/math/RemQuoTest.h
@@ -24,10 +24,10 @@ class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
using StorageType = typename FPBits::StorageType;
using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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/FDimTest.h b/libc/test/src/math/smoke/FDimTest.h
index f40dd172e58b6c..0744e6ea8fd8fe 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<T>;
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::inf(Sign::NEG));
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
};
diff --git a/libc/test/src/math/smoke/FmaTest.h b/libc/test/src/math/smoke/FmaTest.h
index d52c220a827f5f..dc624d871b9901 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<T>;
using StorageType = typename FPBits::StorageType;
- const T nan = T(FPBits::build_quiet_nan(1));
- const T inf = T(FPBits::inf());
+ 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());
+ 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:
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 07e774e1e00a32..77454c19a6538c 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<T>;
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 inf = FPBits::inf(Sign::POS);
const T neg_inf = FPBits::inf(Sign::NEG);
- const T zero = FPBits::zero();
+ 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 f6b56305403551..0a50abc04f727f 100644
--- a/libc/test/src/math/smoke/ILogbTest.h
+++ b/libc/test/src/math/smoke/ILogbTest.h
@@ -25,10 +25,11 @@ class LlvmLibcILogbTest : public LIBC_NAMESPACE::testing::Test {
template <typename T>
void test_special_numbers(typename ILogbFunc<T>::Func func) {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
- EXPECT_EQ(FP_ILOGB0, func(T(FPBits::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::inf(Sign::POS))));
EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::NEG))));
}
diff --git a/libc/test/src/math/smoke/LdExpTest.h b/libc/test/src/math/smoke/LdExpTest.h
index 9e7ecd83f7b9bb..b507bb4ec56e55 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<T>;
using NormalFloat = LIBC_NAMESPACE::fputil::NormalFloat<T>;
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::zero(Sign::NEG));
- const T inf = T(FPBits::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 66f7f587f653bf..d7eb60eec4ede4 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -32,12 +32,14 @@ template <typename T>
class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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 1d80a67f25a5ed..af4e0ab14531c1 100644
--- a/libc/test/src/math/smoke/NextTowardTest.h
+++ b/libc/test/src/math/smoke/NextTowardTest.h
@@ -34,11 +34,12 @@ class NextTowardTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using ToFPBits = LIBC_NAMESPACE::fputil::FPBits<long double>;
using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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();
diff --git a/libc/test/src/math/smoke/RIntTest.h b/libc/test/src/math/smoke/RIntTest.h
index 1523f81ae87bf5..b242c7e441b69f 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<T>;
using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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 127c1632f80bb7..93e20747e52638 100644
--- a/libc/test/src/math/smoke/RemQuoTest.h
+++ b/libc/test/src/math/smoke/RemQuoTest.h
@@ -19,11 +19,12 @@ template <typename T>
class RemQuoTestTemplate : public LIBC_NAMESPACE::testing::Test {
using FPBits = LIBC_NAMESPACE::fputil::FPBits<T>;
using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
- const T zero = T(FPBits::zero());
- const T neg_zero = T(FPBits::zero(Sign::NEG));
- const T inf = T(FPBits::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 2850b06605ce8e..2703b78f00e0f1 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<F>;
using StorageType = typename FPBits::StorageType;
+ using Sign = LIBC_NAMESPACE::fputil::Sign;
- const F zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::zero());
+ const F zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::zero(Sign::POS));
const F neg_zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::zero(Sign::NEG));
- const F inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::inf());
- const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::neg_inf());
+ const F inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::inf(Sign::POS));
+ const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::inf(Sign::NEG));
const F nan = F(LIBC_NAMESPACE::fputil::FPBits<F>::build_quiet_nan(1));
static constexpr I INTEGER_MIN = I(1) << (sizeof(I) * 8 - 1);
static constexpr I INTEGER_MAX = -(INTEGER_MIN + 1);
>From 36e386f2f07f7b1b3f6f5d3f7cf00264714bfa54 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 18 Jan 2024 10:30:06 +0000
Subject: [PATCH 07/10] Force creation of Sign through Sign::NEG / Sign::POS
---
libc/src/__support/FPUtil/BasicOperations.h | 2 +-
libc/src/__support/FPUtil/DivisionAndRemainderOperations.h | 6 +++---
libc/src/__support/FPUtil/FPBits.h | 6 +++---
libc/src/__support/FPUtil/NormalFloat.h | 2 +-
libc/src/__support/FPUtil/dyadic_float.h | 2 +-
libc/src/__support/FPUtil/generic/FMA.h | 2 +-
libc/src/math/generic/powf.cpp | 4 ++--
7 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/libc/src/__support/FPUtil/BasicOperations.h b/libc/src/__support/FPUtil/BasicOperations.h
index 4015edb1b65372..ea78809dfc7f7d 100644
--- a/libc/src/__support/FPUtil/BasicOperations.h
+++ b/libc/src/__support/FPUtil/BasicOperations.h
@@ -36,7 +36,7 @@ LIBC_INLINE T fmin(T x, T y) {
// 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.is_neg()) ? x : y);
+ return (bitx.is_neg()) ? x : y;
} else {
return (x < y ? x : y);
}
diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
index d3401b10a7cab8..71dbc2cc879783 100644
--- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
+++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
@@ -43,7 +43,7 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
return x;
}
- bool result_sign = (xbits.is_neg() == ybits.is_neg() ? 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
@@ -72,7 +72,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 +107,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 990b88d18efeef..3ee6289b749648 100644
--- a/libc/src/__support/FPUtil/FPBits.h
+++ b/libc/src/__support/FPUtil/FPBits.h
@@ -34,9 +34,6 @@ enum class FPType {
// A type to interact with floating point type signs.
// This may be moved outside of 'fputil' if useful.
struct Sign {
- LIBC_INLINE constexpr explicit Sign(bool is_negative)
- : is_negative(is_negative) {}
-
LIBC_INLINE constexpr bool is_pos() const { return !is_negative; }
LIBC_INLINE constexpr bool is_neg() const { return is_negative; }
@@ -51,6 +48,9 @@ struct Sign {
static const Sign NEG;
private:
+ LIBC_INLINE constexpr explicit Sign(bool is_negative)
+ : is_negative(is_negative) {}
+
bool is_negative;
};
diff --git a/libc/src/__support/FPUtil/NormalFloat.h b/libc/src/__support/FPUtil/NormalFloat.h
index 39376bfcba0319..8b1612e1b47c61 100644
--- a/libc/src/__support/FPUtil/NormalFloat.h
+++ b/libc/src/__support/FPUtil/NormalFloat.h
@@ -47,7 +47,7 @@ template <typename T> struct NormalFloat {
Sign sign = Sign::POS;
LIBC_INLINE NormalFloat(int32_t e, StorageType m, bool s)
- : exponent(e), mantissa(m), sign(Sign(s)) {
+ : exponent(e), mantissa(m), sign(s ? Sign::NEG : Sign::POS) {
if (mantissa >= ONE)
return;
diff --git a/libc/src/__support/FPUtil/dyadic_float.h b/libc/src/__support/FPUtil/dyadic_float.h
index 3cc3890b65a01b..439741d2c497c0 100644
--- a/libc/src/__support/FPUtil/dyadic_float.h
+++ b/libc/src/__support/FPUtil/dyadic_float.h
@@ -50,7 +50,7 @@ template <size_t Bits> struct DyadicFloat {
}
constexpr DyadicFloat(bool s, int e, MantissaType m)
- : sign(Sign(s)), exponent(e), mantissa(m) {
+ : sign(s ? Sign::NEG : Sign::POS), exponent(e), mantissa(m) {
normalize();
}
diff --git a/libc/src/__support/FPUtil/generic/FMA.h b/libc/src/__support/FPUtil/generic/FMA.h
index 2aaf6ce369a37a..9c67c645d5243d 100644
--- a/libc/src/__support/FPUtil/generic/FMA.h
+++ b/libc/src/__support/FPUtil/generic/FMA.h
@@ -119,7 +119,7 @@ template <> LIBC_INLINE double fma<double>(double x, double y, double z) {
FPBits x_bits(x), y_bits(y), z_bits(z);
const Sign z_sign = z_bits.sign();
- Sign prod_sign = Sign(x_bits.sign() != y_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();
diff --git a/libc/src/math/generic/powf.cpp b/libc/src/math/generic/powf.cpp
index f1be147298a410..932f1d70c33e8e 100644
--- a/libc/src/math/generic/powf.cpp
+++ b/libc/src/math/generic/powf.cpp
@@ -617,7 +617,7 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
// pow(0, negative number) = inf
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_DIVBYZERO);
- return FloatBits::inf(Sign(out_is_neg));
+ return FloatBits::inf(out_is_neg ? Sign::NEG : Sign::POS);
}
// pow(0, positive number) = 0
return out_is_neg ? -0.0f : 0.0f;
@@ -628,7 +628,7 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
if (y_u >= FloatBits::SIGN_MASK) {
return out_is_neg ? -0.0f : 0.0f;
}
- return FloatBits::inf(Sign(out_is_neg));
+ return FloatBits::inf(out_is_neg ? Sign::NEG : Sign::POS);
}
}
>From a8f74e27d6c832e551d4d7179a09f148063c2d5c Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 18 Jan 2024 10:32:30 +0000
Subject: [PATCH 08/10] Use Sign instead of bool in fpbits_str.h
---
libc/src/__support/FPUtil/fpbits_str.h | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/libc/src/__support/FPUtil/fpbits_str.h b/libc/src/__support/FPUtil/fpbits_str.h
index b48def8b1cdcf4..a1654cddad7464 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 <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
using StorageType = typename fputil::FPBits<T>::StorageType;
+ using Sign = fputil::Sign;
if (x.is_nan())
return "(NaN)";
if (x.is_inf())
return x.is_neg() ? "(-Infinity)" : "(+Infinity)";
- const auto sign_char = [](bool is_neg) -> char { return is_neg ? '1' : '0'; };
+ const auto sign_char = [](Sign sign) -> char {
+ return sign.is_neg() ? '1' : '0';
+ };
cpp::string s;
@@ -49,7 +52,7 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
s += bits.view();
s += " = (S: ";
- s += sign_char(x.is_neg());
+ s += sign_char(x.sign());
s += ", E: ";
const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
@@ -57,7 +60,7 @@ template <typename T> LIBC_INLINE cpp::string str(fputil::FPBits<T> x) {
if constexpr (fputil::get_fp_type<T>() == 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: ";
>From a2e782df42ff3b548985f8fbfc24686fa8cb4155 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 18 Jan 2024 10:35:19 +0000
Subject: [PATCH 09/10] Add comment about leaking abstraction.
---
libc/src/math/generic/expm1.cpp | 2 ++
1 file changed, 2 insertions(+)
diff --git a/libc/src/math/generic/expm1.cpp b/libc/src/math/generic/expm1.cpp
index 3d343a99d1c288..71c4663edd21a8 100644
--- a/libc/src/math/generic/expm1.cpp
+++ b/libc/src/math/generic/expm1.cpp
@@ -438,6 +438,8 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) {
double lo = fputil::multiply_add(p, mid_lo, hi_part.lo);
+ // TODO: The following line leaks encoding abstraction. Use FPBits methods
+ // instead.
uint64_t err = x_is_neg ? (static_cast<uint64_t>(-hi) << 52) : 0;
double err_d = cpp::bit_cast<double>(ERR_D + err);
>From afe74f31a3250fcd63b3ffed324d5a5f38c01b13 Mon Sep 17 00:00:00 2001
From: Guillaume Chatelet <gchatelet at google.com>
Date: Thu, 18 Jan 2024 10:42:56 +0000
Subject: [PATCH 10/10] Fix formatting
---
libc/src/__support/FPUtil/DivisionAndRemainderOperations.h | 3 ++-
libc/test/src/math/NextAfterTest.h | 2 +-
libc/test/src/math/smoke/NextAfterTest.h | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
index 71dbc2cc879783..1c09e7906165f5 100644
--- a/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
+++ b/libc/src/__support/FPUtil/DivisionAndRemainderOperations.h
@@ -43,7 +43,8 @@ LIBC_INLINE T remquo(T x, T y, int &q) {
return x;
}
- const Sign result_sign = (xbits.sign() == ybits.sign() ? Sign::POS : Sign::NEG);
+ 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
diff --git a/libc/test/src/math/NextAfterTest.h b/libc/test/src/math/NextAfterTest.h
index 2dc848b3ea36a0..aa9646fd921f81 100644
--- a/libc/test/src/math/NextAfterTest.h
+++ b/libc/test/src/math/NextAfterTest.h
@@ -28,7 +28,7 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
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/NextAfterTest.h b/libc/test/src/math/smoke/NextAfterTest.h
index d7eb60eec4ede4..bdf3da627180aa 100644
--- a/libc/test/src/math/smoke/NextAfterTest.h
+++ b/libc/test/src/math/smoke/NextAfterTest.h
@@ -39,7 +39,7 @@ class NextAfterTestTemplate : public LIBC_NAMESPACE::testing::Test {
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;
More information about the libc-commits
mailing list