35 changes: 12 additions & 23 deletions libc/src/__support/FPUtil/NearestIntegerOperations.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,8 @@ LIBC_INLINE T trunc(T x) {
return x;

// If the exponent is such that abs(x) is less than 1, then return 0.
if (exponent <= -1) {
if (bits.get_sign())
return T(-0.0);
else
return T(0.0);
}
if (exponent <= -1)
return T(FPBits<T>::zero(bits.sign()));

int trim_size = FPBits<T>::FRACTION_LEN - exponent;
bits.set_mantissa((bits.get_mantissa() >> trim_size) << trim_size);
Expand All @@ -60,7 +56,7 @@ LIBC_INLINE T ceil(T x) {
if (bits.is_inf_or_nan() || bits.is_zero())
return x;

bool is_neg = bits.get_sign();
bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();

// If the exponent is greater than the most negative mantissa
Expand Down Expand Up @@ -93,7 +89,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);
Expand All @@ -109,7 +105,6 @@ LIBC_INLINE T round(T x) {
if (bits.is_inf_or_nan() || bits.is_zero())
return x;

bool is_neg = bits.get_sign();
int exponent = bits.get_exponent();

// If the exponent is greater than the most negative mantissa
Expand All @@ -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;
Expand All @@ -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);
}
}

Expand All @@ -161,7 +150,7 @@ LIBC_INLINE T round_using_current_rounding_mode(T x) {
if (bits.is_inf_or_nan() || bits.is_zero())
return x;

bool is_neg = bits.get_sign();
bool is_neg = bits.is_neg();
int exponent = bits.get_exponent();
int rounding_mode = quick_get_round();

Expand Down Expand Up @@ -247,18 +236,18 @@ LIBC_INLINE I rounded_float_to_signed_integer(F x) {

if (bits.is_inf_or_nan()) {
set_domain_error_and_raise_invalid();
return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX;
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
}

int exponent = bits.get_exponent();
constexpr int EXPONENT_LIMIT = sizeof(I) * 8 - 1;
if (exponent > EXPONENT_LIMIT) {
set_domain_error_and_raise_invalid();
return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX;
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
} else if (exponent == EXPONENT_LIMIT) {
if (bits.get_sign() == 0 || bits.get_mantissa() != 0) {
if (bits.is_pos() || bits.get_mantissa() != 0) {
set_domain_error_and_raise_invalid();
return bits.get_sign() ? INTEGER_MIN : INTEGER_MAX;
return bits.is_neg() ? INTEGER_MIN : INTEGER_MAX;
}
// If the control reaches here, then it means that the rounded
// value is the most negative number for the signed integer type I.
Expand Down
23 changes: 12 additions & 11 deletions libc/src/__support/FPUtil/NormalFloat.h
Original file line number Diff line number Diff line change
Expand Up @@ -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(s ? Sign::NEG : Sign::POS) {
if (mantissa >= ONE)
return;

Expand All @@ -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;
}
}

Expand All @@ -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));
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 5 additions & 5 deletions libc/src/__support/FPUtil/dyadic_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand All @@ -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(s ? Sign::NEG : Sign::POS), exponent(e), mantissa(m) {
normalize();
}

Expand Down Expand Up @@ -172,7 +172,7 @@ template <size_t Bits> struct DyadicFloat {
new_mant >>= (-exponent);
}

if (sign) {
if (sign.is_neg()) {
new_mant = (~new_mant) + 1;
}

Expand Down Expand Up @@ -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())) {
Expand Down
11 changes: 7 additions & 4 deletions libc/src/__support/FPUtil/fpbits_str.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,29 +35,32 @@ 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.get_sign() ? "(-Infinity)" : "(+Infinity)";
return x.is_neg() ? "(-Infinity)" : "(+Infinity)";

const auto sign_char = [](bool sign) -> char { return sign ? '1' : '0'; };
const auto sign_char = [](Sign sign) -> char {
return sign.is_neg() ? '1' : '0';
};

cpp::string s;

const details::ZeroPaddedHexFmt<StorageType> bits(x.uintval());
s += bits.view();

s += " = (S: ";
s += sign_char(x.get_sign());
s += sign_char(x.sign());

s += ", E: ";
const details::ZeroPaddedHexFmt<uint16_t> exponent(x.get_biased_exponent());
s += exponent.view();

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: ";
Expand Down
27 changes: 12 additions & 15 deletions libc/src/__support/FPUtil/generic/FMA.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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.get_sign();
bool y_sign = y_bits.get_sign();
bool z_sign = z_bits.get_sign();
bool prod_sign = x_sign != y_sign;
const Sign z_sign = z_bits.sign();
Sign prod_sign = (x_bits.sign() == y_bits.sign()) ? Sign::POS : Sign::NEG;
x_exp += x_bits.get_biased_exponent();
y_exp += y_bits.get_biased_exponent();
z_exp += z_bits.get_biased_exponent();
Expand Down Expand Up @@ -248,36 +246,35 @@ 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;
}

// Rounding.
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;
}
Expand Down
6 changes: 3 additions & 3 deletions libc/src/__support/FPUtil/generic/FMod.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/FPUtil/generic/sqrt.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions libc/src/__support/FPUtil/generic/sqrt_80_bit_long_double.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
4 changes: 0 additions & 4 deletions libc/src/__support/float_to_string.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -421,14 +420,11 @@ class FloatToString {

public:
LIBC_INLINE constexpr FloatToString(T init_float) : float_bits(init_float) {
is_negative = float_bits.get_sign();
exponent = float_bits.get_explicit_exponent();
mantissa = float_bits.get_explicit_mantissa();

// Adjust for the width of the mantissa.
exponent -= FRACTION_LEN;

// init_convert();
}

LIBC_INLINE constexpr bool is_nan() { return float_bits.is_nan(); }
Expand Down
16 changes: 4 additions & 12 deletions libc/src/__support/str_to_float.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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 = '.';
Expand Down Expand Up @@ -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] &&
Expand Down
3 changes: 2 additions & 1 deletion libc/src/math/generic/acosf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
3 changes: 2 additions & 1 deletion libc/src/math/generic/asinf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 6 additions & 4 deletions libc/src/math/generic/atanf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -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();
Expand Down
3 changes: 2 additions & 1 deletion libc/src/math/generic/atanhf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion libc/src/math/generic/cosf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down
3 changes: 2 additions & 1 deletion libc/src/math/generic/coshf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/erff.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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];
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/exp10f_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/exp2f_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/expf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
13 changes: 8 additions & 5 deletions libc/src/math/generic/expm1.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -437,7 +438,9 @@ LLVM_LIBC_FUNCTION(double, expm1, (double x)) {

double lo = fputil::multiply_add(p, mid_lo, hi_part.lo);

uint64_t err = x_sign ? (static_cast<uint64_t>(-hi) << 52) : 0;
// 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);

Expand Down
2 changes: 1 addition & 1 deletion libc/src/math/generic/expm1f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 6 additions & 5 deletions libc/src/math/generic/inv_trigf_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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();
Expand All @@ -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|],
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -747,9 +747,9 @@ LLVM_LIBC_FUNCTION(double, log, (double x)) {
// return -Inf and raise FE_DIVBYZERO.
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits_t::build_quiet_nan(0);
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log10.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -748,9 +748,9 @@ LLVM_LIBC_FUNCTION(double, log10, (double x)) {
// return -Inf and raise FE_DIVBYZERO.
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits_t::build_quiet_nan(0);
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log10f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,9 @@ LLVM_LIBC_FUNCTION(float, log10f, (float x)) {
// Return -inf and raise FE_DIVBYZERO
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
// Return NaN and raise FE_INVALID
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log1p.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -892,9 +892,9 @@ LLVM_LIBC_FUNCTION(double, log1p, (double x)) {
// x = -1.0
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
// x < -1.0
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log1pf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -869,9 +869,9 @@ LLVM_LIBC_FUNCTION(double, log2, (double x)) {
// return -Inf and raise FE_DIVBYZERO.
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<double>(FPBits_t::neg_inf());
return static_cast<double>(FPBits_t::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
return FPBits_t::build_quiet_nan(0);
Expand Down
4 changes: 2 additions & 2 deletions libc/src/math/generic/log2f.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@ LLVM_LIBC_FUNCTION(float, log2f, (float x)) {
if (xbits.is_zero()) {
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
fputil::set_errno_if_required(EDOM);
fputil::raise_except(FE_INVALID);
return FPBits::build_quiet_nan(0);
Expand Down
6 changes: 3 additions & 3 deletions libc/src/math/generic/logf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -117,9 +117,9 @@ LLVM_LIBC_FUNCTION(float, logf, (float x)) {
// Return -inf and raise FE_DIVBYZERO
fputil::set_errno_if_required(ERANGE);
fputil::raise_except_if_required(FE_DIVBYZERO);
return static_cast<float>(FPBits::neg_inf());
return static_cast<float>(FPBits::inf(fputil::Sign::NEG));
}
if (xbits.get_sign() && !xbits.is_nan()) {
if (xbits.is_neg() && !xbits.is_nan()) {
// Return NaN and raise FE_INVALID
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_INVALID);
Expand Down
26 changes: 14 additions & 12 deletions libc/src/math/generic/powf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand All @@ -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();
Expand Down Expand Up @@ -605,28 +607,28 @@ LLVM_LIBC_FUNCTION(float, powf, (float x, float y)) {
return generic::exp10f(y);
}

bool x_sign = x_u >= FloatBits::SIGN_MASK;
const bool x_is_neg = x_u >= FloatBits::SIGN_MASK;

switch (x_abs) {
case 0x0000'0000: { // x = +-0.0f
bool x_sign = (x_u >= FloatBits::SIGN_MASK);
bool out_sign = x_sign && is_odd_integer(FloatBits(y_u).get_val());
const bool out_is_neg =
x_is_neg && is_odd_integer(FloatBits(y_u).get_val());
if (y_u > 0x8000'0000U) {
// pow(0, negative number) = inf
fputil::set_errno_if_required(EDOM);
fputil::raise_except_if_required(FE_DIVBYZERO);
return FloatBits::inf(out_sign);
return FloatBits::inf(out_is_neg ? Sign::NEG : Sign::POS);
}
// pow(0, positive number) = 0
return out_sign ? -0.0f : 0.0f;
return out_is_neg ? -0.0f : 0.0f;
}
case 0x7f80'0000: { // x = +-Inf
bool x_sign = (x_u >= FloatBits::SIGN_MASK);
bool out_sign = x_sign && is_odd_integer(FloatBits(y_u).get_val());
const bool out_is_neg =
x_is_neg && is_odd_integer(FloatBits(y_u).get_val());
if (y_u >= FloatBits::SIGN_MASK) {
return out_sign ? -0.0f : 0.0f;
return out_is_neg ? -0.0f : 0.0f;
}
return FloatBits::inf(out_sign);
return FloatBits::inf(out_is_neg ? Sign::NEG : Sign::POS);
}
}

Expand All @@ -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)) {
Expand Down
6 changes: 3 additions & 3 deletions libc/src/math/generic/sinf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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)) {
Expand Down
5 changes: 2 additions & 3 deletions libc/src/math/generic/sinhf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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.
Expand Down
11 changes: 5 additions & 6 deletions libc/src/math/generic/tanhf.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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
Expand All @@ -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))
Expand Down
21 changes: 9 additions & 12 deletions libc/src/stdio/printf_core/float_dec_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -567,7 +566,7 @@ LIBC_INLINE int convert_float_decimal_typed(Writer *writer,
const bool truncated = !zero_after_digits(
exponent - FRACTION_LEN, precision,
float_bits.get_explicit_mantissa(), FRACTION_LEN);
round = get_round_direction(last_digit, truncated, is_negative);
round = get_round_direction(last_digit, truncated, float_bits.sign());

RET_IF_RESULT_NEGATIVE(
float_writer.write_last_block(digits, maximum, round));
Expand All @@ -587,15 +586,14 @@ 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();

const char a = (to_conv.conv_name & 32) | 'A';

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
Expand Down Expand Up @@ -735,7 +733,7 @@ LIBC_INLINE int convert_float_dec_exp_typed(Writer *writer,
float_bits.get_explicit_mantissa(), FRACTION_LEN);
}
}
round = get_round_direction(last_digit, truncated, is_negative);
round = get_round_direction(last_digit, truncated, float_bits.sign());

RET_IF_RESULT_NEGATIVE(float_writer.write_last_block(
digits, maximum, round, final_exponent, a + 'E' - 'A'));
Expand All @@ -750,7 +748,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();

Expand Down Expand Up @@ -983,7 +980,7 @@ LIBC_INLINE int convert_float_dec_auto_typed(Writer *writer,
}
}

round = get_round_direction(last_digit, truncated, is_negative);
round = get_round_direction(last_digit, truncated, float_bits.sign());

bool round_up;
if (round == RoundDirection::Up) {
Expand Down
4 changes: 2 additions & 2 deletions libc/src/stdio/printf_core/float_hex_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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();
Expand Down
4 changes: 2 additions & 2 deletions libc/src/stdio/printf_core/float_inf_nan_converter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}

Expand Down
18 changes: 10 additions & 8 deletions libc/test/UnitTest/FPMatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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(); \
Expand Down
102 changes: 56 additions & 46 deletions libc/test/src/__support/FPUtil/fpbits_test.cpp

Large diffs are not rendered by default.

16 changes: 7 additions & 9 deletions libc/test/src/math/FDimTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -72,13 +79,4 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
}
}
}

private:
// constexpr does not work on FPBits yet, so we cannot have these constants as
// static.
const T nan = T(FPBits::build_quiet_nan(1));
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T zero = T(FPBits::zero());
const T neg_zero = T(FPBits::neg_zero());
};
10 changes: 6 additions & 4 deletions libc/test/src/math/FmaTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
using Sign = LIBC_NAMESPACE::fputil::Sign;

const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T zero = T(FPBits::zero());
const T neg_zero = T(FPBits::neg_zero());

StorageType get_random_bit_pattern() {
StorageType bits{0};
Expand Down
5 changes: 3 additions & 2 deletions libc/test/src/math/HypotTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand Down
5 changes: 3 additions & 2 deletions libc/test/src/math/ILogbTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
14 changes: 8 additions & 6 deletions libc/test/src/math/LdExpTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

// A normalized mantissa to be used with tests.
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;

public:
typedef T (*LdExpFunc)(T, int);

Expand Down
10 changes: 6 additions & 4 deletions libc/test/src/math/NextAfterTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

const StorageType min_subnormal = FPBits::MIN_SUBNORMAL;
const StorageType max_subnormal = FPBits::MAX_SUBNORMAL;
const StorageType min_normal = FPBits::MIN_NORMAL;
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/RIntTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

static inline mpfr::RoundingMode to_mpfr_rounding_mode(int mode) {
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/RemQuoTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

public:
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/RoundToIntegerTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,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(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);
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions libc/test/src/math/atanhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down
16 changes: 7 additions & 9 deletions libc/test/src/math/smoke/FDimTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -72,13 +79,4 @@ class FDimTestTemplate : public LIBC_NAMESPACE::testing::Test {
}
}
}

private:
// constexpr does not work on FPBits yet, so we cannot have these constants as
// static.
const T nan = T(FPBits::build_quiet_nan(1));
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T zero = T(FPBits::zero());
const T neg_zero = T(FPBits::neg_zero());
};
10 changes: 6 additions & 4 deletions libc/test/src/math/smoke/FmaTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
using Sign = LIBC_NAMESPACE::fputil::Sign;

const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T zero = T(FPBits::zero());
const T neg_zero = T(FPBits::neg_zero());

public:
void test_special_numbers(Func func) {
Expand Down
10 changes: 6 additions & 4 deletions libc/test/src/math/smoke/HypotTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 neg_inf = FPBits::neg_inf();
const T zero = FPBits::zero();
const T neg_zero = FPBits::neg_zero();
const T inf = FPBits::inf(Sign::POS);
const T neg_inf = FPBits::inf(Sign::NEG);
const T zero = FPBits::zero(Sign::POS);
const T neg_zero = FPBits::zero(Sign::NEG);

const T max_normal = FPBits::max_normal();
const T min_normal = FPBits::min_normal();
const T max_subnormal = FPBits::max_denormal();
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/smoke/ILogbTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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>;
EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero())));
EXPECT_EQ(FP_ILOGB0, func(T(FPBits::neg_zero())));
using Sign = LIBC_NAMESPACE::fputil::Sign;
EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::POS))));
EXPECT_EQ(FP_ILOGB0, func(T(FPBits::zero(Sign::NEG))));
EXPECT_EQ(FP_ILOGBNAN, func(T(FPBits::build_quiet_nan(1))));
EXPECT_EQ(INT_MAX, func(T(FPBits::inf())));
EXPECT_EQ(INT_MAX, func(T(FPBits::neg_inf())));
EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::POS))));
EXPECT_EQ(INT_MAX, func(T(FPBits::inf(Sign::NEG))));
}

template <typename T>
Expand Down
14 changes: 8 additions & 6 deletions libc/test/src/math/smoke/LdExpTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

// A normalized mantissa to be used with tests.
static constexpr StorageType MANTISSA = NormalFloat::ONE + 0x1234;

public:
typedef T (*LdExpFunc)(T, int);

Expand Down
10 changes: 6 additions & 4 deletions libc/test/src/math/smoke/NextAfterTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

const StorageType min_subnormal = FPBits::MIN_SUBNORMAL;
const StorageType max_subnormal = FPBits::MAX_SUBNORMAL;
const StorageType min_normal = FPBits::MIN_NORMAL;
Expand Down
11 changes: 6 additions & 5 deletions libc/test/src/math/smoke/NextTowardTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,16 @@ 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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

const long double to_zero = ToFPBits::zero();
const long double to_neg_zero = ToFPBits::neg_zero();
const long double to_neg_zero = ToFPBits::zero(Sign::NEG);
const long double to_nan = ToFPBits::build_quiet_nan(1);

const StorageType min_subnormal = FPBits::MIN_SUBNORMAL;
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/smoke/RIntTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

public:
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/smoke/RemQuoTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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::neg_zero());
const T inf = T(FPBits::inf());
const T neg_inf = T(FPBits::neg_inf());
const T inf = T(FPBits::inf(Sign::POS));
const T neg_inf = T(FPBits::inf(Sign::NEG));
const T zero = T(FPBits::zero(Sign::POS));
const T neg_zero = T(FPBits::zero(Sign::NEG));
const T nan = T(FPBits::build_quiet_nan(1));

public:
Expand Down
9 changes: 5 additions & 4 deletions libc/test/src/math/smoke/RoundToIntegerTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 neg_zero = F(LIBC_NAMESPACE::fputil::FPBits<F>::neg_zero());
const F inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::inf());
const F neg_inf = F(LIBC_NAMESPACE::fputil::FPBits<F>::neg_inf());
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(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);
Expand Down
5 changes: 3 additions & 2 deletions libc/test/src/math/smoke/atanhf_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand All @@ -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);
}
2 changes: 1 addition & 1 deletion libc/test/src/stdlib/strtold_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion libc/test/src/time/difftime_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}