static const double inf = FPBits::inf();
static const double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(CeilTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::ceil(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::ceil(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Ceil, x, __llvm_libc::ceil(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Ceil, x, __llvm_libc::ceil(x), 0.0);
}
}
static const float inf = FPBits::inf();
static const float negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(CeilfTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::ceilf(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::ceilf(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Ceil, x, __llvm_libc::ceilf(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Ceil, x, __llvm_libc::ceilf(x), 0.0);
}
}
static const long double inf = FPBits::inf();
static const long double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(CeillTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::ceill(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::ceill(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Ceil, x, __llvm_libc::ceill(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Ceil, x, __llvm_libc::ceill(x), 0.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// 12 additional bits of precision over the base precision of a |float|
-// value.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 12,
- 3 * 0x1000 / 4};
-
TEST(CosfTest, SpecialNumbers) {
llvmlibc_errno = 0;
float x = valueFromBits(v);
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, __llvm_libc::cosf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, __llvm_libc::cosf(x), 1.0);
}
}
TEST(CosfTest, SmallValues) {
float x = valueFromBits(0x17800000U);
float result = __llvm_libc::cosf(x);
- EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result, 1.0);
EXPECT_EQ(BitPatterns::one, valueAsBits(result));
x = valueFromBits(0x0040000U);
result = __llvm_libc::cosf(x);
- EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result, 1.0);
EXPECT_EQ(BitPatterns::one, valueAsBits(result));
}
TEST(CosfTest, SDCOMP_26094) {
for (uint32_t v : sdcomp26094Values) {
float x = valueFromBits(v);
- ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, __llvm_libc::cosf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, __llvm_libc::cosf(x), 1.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// 12 additional bits of precision over the base precision of a |float|
-// value.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 12,
- 0xFFF};
-
TEST(exp2fTest, SpecialNumbers) {
llvmlibc_errno = 0;
llvmlibc_errno = 0;
x = valueFromBits(0x42fa0001U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0x42ffffffU);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0xc2fa0001U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0xc2fc0000U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0xc2fc0001U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0xc3150000U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
}
llvmlibc_errno = 0;
float x = valueFromBits(0xc3158000U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, ERANGE);
llvmlibc_errno = 0;
x = valueFromBits(0xc3165432U);
- EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
EXPECT_EQ(llvmlibc_errno, ERANGE);
}
// wider precision.
if (isnan(result) || isinf(result) || llvmlibc_errno != 0)
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Exp2, x, __llvm_libc::exp2f(x), 1.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// 12 additional bits of precision over the base precision of a |float|
-// value.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 12,
- 0xFFF};
-
TEST(ExpfTest, SpecialNumbers) {
llvmlibc_errno = 0;
llvmlibc_errno = 0;
x = valueFromBits(0x42affff8U);
- ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0x42b00008U);
- ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0xc2affff8U);
- ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
x = valueFromBits(0xc2b00008U);
- ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
EXPECT_EQ(llvmlibc_errno, 0);
}
// wider precision.
if (isnan(result) || isinf(result) || llvmlibc_errno != 0)
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Exp, x, __llvm_libc::expf(x), 1.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::doublePrecision, 0,
- 0};
-
TEST(FabsTest, SpecialNumbers) {
EXPECT_FP_EQ(nan, __llvm_libc::fabs(nan));
double x = FPBits(v);
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, __llvm_libc::fabs(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, __llvm_libc::fabs(x), 0.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
-
TEST(FabsfTest, SpecialNumbers) {
EXPECT_FP_EQ(nan, __llvm_libc::fabsf(nan));
float x = FPBits(v);
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, __llvm_libc::fabsf(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, __llvm_libc::fabsf(x), 0.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
-
TEST(FabslTest, SpecialNumbers) {
EXPECT_FP_EQ(nan, __llvm_libc::fabsl(nan));
long double x = FPBits(v);
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, __llvm_libc::fabsl(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Abs, x, __llvm_libc::fabsl(x), 0.0);
}
}
static const double inf = FPBits::inf();
static const double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(FloorTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::floor(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::floor(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Floor, x, __llvm_libc::floor(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Floor, x, __llvm_libc::floor(x), 0.0);
}
}
static const float inf = FPBits::inf();
static const float negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(FloorfTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::floorf(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::floorf(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Floor, x, __llvm_libc::floorf(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Floor, x, __llvm_libc::floorf(x), 0.0);
}
}
static const long double inf = FPBits::inf();
static const long double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(FloorlTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::floorl(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::floorl(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Floor, x, __llvm_libc::floorl(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Floor, x, __llvm_libc::floorl(x), 0.0);
}
}
static const double inf = FPBits::inf();
static const double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(RoundTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::round(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::round(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::round(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::round(x), 0.0);
}
}
static const float inf = FPBits::inf();
static const float negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(RoundfTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::roundf(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::roundf(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::roundf(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::roundf(x), 0.0);
}
}
static const long double inf = FPBits::inf();
static const long double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(RoundlTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::roundl(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::roundl(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::roundl(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Round, x, __llvm_libc::roundl(x), 0.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// 12 additional bits of precision over the base precision of a |float|
-// value.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 12,
- 3 * 0x1000 / 4};
-
TEST(SinCosfTest, SpecialNumbers) {
llvmlibc_errno = 0;
float sin, cos;
float sin, cos;
__llvm_libc::sincosf(x, &sin, &cos);
- ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, cos, tolerance);
- ASSERT_MPFR_MATCH(mpfr::Operation::Sin, x, sin, tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Cos, x, cos, 1.0);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Sin, x, sin, 1.0);
}
}
float x = valueFromBits(bits);
float result_cos, result_sin;
__llvm_libc::sincosf(x, &result_sin, &result_cos);
- EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result_cos, tolerance);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result_sin, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result_cos, 1.0);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result_sin, 1.0);
EXPECT_EQ(BitPatterns::one, valueAsBits(result_cos));
EXPECT_EQ(bits, valueAsBits(result_sin));
bits = 0x00400000;
x = valueFromBits(bits);
__llvm_libc::sincosf(x, &result_sin, &result_cos);
- EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result_cos, tolerance);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result_sin, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, result_cos, 1.0);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result_sin, 1.0);
EXPECT_EQ(BitPatterns::one, valueAsBits(result_cos));
EXPECT_EQ(bits, valueAsBits(result_sin));
}
float x = valueFromBits(v);
float sin, cos;
__llvm_libc::sincosf(x, &sin, &cos);
- EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, cos, tolerance);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, sin, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Cos, x, cos, 1.0);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, sin, 1.0);
}
}
namespace mpfr = __llvm_libc::testing::mpfr;
-// 12 additional bits of precision over the base precision of a |float|
-// value.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 12,
- 3 * 0x1000 / 4};
-
TEST(SinfTest, SpecialNumbers) {
llvmlibc_errno = 0;
float x = valueFromBits(v);
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x), tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x), 1.0);
}
}
TEST(SinfTest, SpecificBitPatterns) {
float x = valueFromBits(0xc70d39a1);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x), 1.0);
}
// For small values, sin(x) is x.
uint32_t bits = 0x17800000;
float x = valueFromBits(bits);
float result = __llvm_libc::sinf(x);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result, 1.0);
EXPECT_EQ(bits, valueAsBits(result));
bits = 0x00400000;
x = valueFromBits(bits);
result = __llvm_libc::sinf(x);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result, tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, result, 1.0);
EXPECT_EQ(bits, valueAsBits(result));
}
TEST(SinfTest, SDCOMP_26094) {
for (uint32_t v : sdcomp26094Values) {
float x = valueFromBits(v);
- EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x), tolerance);
+ EXPECT_MPFR_MATCH(mpfr::Operation::Sin, x, __llvm_libc::sinf(x), 1.0);
}
}
static const double inf = FPBits::inf();
static const double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(TruncTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::trunc(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::trunc(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Trunc, x, __llvm_libc::trunc(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Trunc, x, __llvm_libc::trunc(x), 0.0);
}
}
static const float inf = FPBits::inf();
static const float negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(TruncfTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::truncf(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::truncf(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Trunc, x, __llvm_libc::truncf(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Trunc, x, __llvm_libc::truncf(x), 0.0);
}
}
static const long double inf = FPBits::inf();
static const long double negInf = FPBits::negInf();
-// Zero tolerance; As in, exact match with MPFR result.
-static constexpr mpfr::Tolerance tolerance{mpfr::Tolerance::floatPrecision, 0,
- 0};
TEST(TrunclTest, SpecialNumbers) {
EXPECT_FP_EQ(zero, __llvm_libc::truncl(zero));
EXPECT_FP_EQ(negZero, __llvm_libc::truncl(negZero));
if (isnan(x) || isinf(x))
continue;
- ASSERT_MPFR_MATCH(mpfr::Operation::Trunc, x, __llvm_libc::truncl(x),
- tolerance);
+ ASSERT_MPFR_MATCH(mpfr::Operation::Trunc, x, __llvm_libc::truncl(x), 0.0);
}
}
mpfr_set_sj(value, x, MPFR_RNDN);
}
- template <typename XType> MPFRNumber(XType x, const Tolerance &t) {
- mpfr_init2(value, mpfrPrecision);
- mpfr_set_zero(value, 1); // Set to positive zero.
- MPFRNumber xExponent(fputil::FPBits<XType>(x).getExponent());
- // E = 2^E
- mpfr_exp2(xExponent.value, xExponent.value, MPFR_RNDN);
- uint32_t bitMask = 1 << (t.width - 1);
- for (int n = -t.basePrecision; bitMask > 0; bitMask >>= 1) {
- --n;
- if (t.bits & bitMask) {
- // delta = -n
- MPFRNumber delta(n);
-
- // delta = 2^(-n)
- mpfr_exp2(delta.value, delta.value, MPFR_RNDN);
-
- // delta = E * 2^(-n)
- mpfr_mul(delta.value, delta.value, xExponent.value, MPFR_RNDN);
-
- // tolerance += delta
- mpfr_add(value, value, delta.value, MPFR_RNDN);
- }
- }
- }
-
template <typename XType,
cpp::EnableIfType<cpp::IsFloatingPointType<XType>::Value, int> = 0>
MPFRNumber(Operation op, XType rawValue) {
~MPFRNumber() { mpfr_clear(value); }
- // Returns true if |other| is within the |tolerance| value of this
- // number.
- bool isEqual(const MPFRNumber &other, const MPFRNumber &tolerance) const {
- MPFRNumber difference;
- if (mpfr_cmp(value, other.value) >= 0)
- mpfr_sub(difference.value, value, other.value, MPFR_RNDN);
- else
- mpfr_sub(difference.value, other.value, value, MPFR_RNDN);
-
- return mpfr_lessequal_p(difference.value, tolerance.value);
- }
-
std::string str() const {
// 200 bytes should be more than sufficient to hold a 100-digit number
// plus additional bytes for the decimal point, '-' sign etc.
__llvm_libc::fputil::testing::describeValue(
" MPFR rounded: ", mpfrResult.as<T>(), OS);
OS << '\n';
- if (useULP) {
- OS << " ULP error: " << std::to_string(mpfrResult.ulp(matchValue))
- << '\n';
- } else {
- MPFRNumber mpfrToleranceValue = MPFRNumber(matchValue, tolerance);
- OS << "Tolerance value: " << mpfrToleranceValue.str() << '\n';
- }
+ OS << " ULP error: " << std::to_string(mpfrResult.ulp(matchValue))
+ << '\n';
}
template void MPFRMatcher<float>::explainError(testutils::StreamWrapper &);
MPFRMatcher<long double>::explainError(testutils::StreamWrapper &);
template <typename T>
-bool compare(Operation op, T input, T libcResult, const Tolerance &t) {
- MPFRNumber mpfrResult(op, input);
- MPFRNumber mpfrLibcResult(libcResult);
- MPFRNumber mpfrToleranceValue(libcResult, t);
-
- return mpfrResult.isEqual(mpfrLibcResult, mpfrToleranceValue);
-};
-
-template bool compare<float>(Operation, float, float, const Tolerance &);
-template bool compare<double>(Operation, double, double, const Tolerance &);
-template bool compare<long double>(Operation, long double, long double,
- const Tolerance &);
-
-template <typename T>
bool compare(Operation op, T input, T libcResult, double ulpError) {
// If the ulp error is exactly 0.5 (i.e a tie), we would check that the result
// is rounded to the nearest even.
namespace testing {
namespace mpfr {
-struct Tolerance {
- // Number of bits used to represent the fractional
- // part of a value of type 'float'.
- static constexpr unsigned int floatPrecision = 23;
-
- // Number of bits used to represent the fractional
- // part of a value of type 'double'.
- static constexpr unsigned int doublePrecision = 52;
-
- // The base precision of the number. For example, for values of
- // type float, the base precision is the value |floatPrecision|.
- unsigned int basePrecision;
-
- unsigned int width; // Number of valid LSB bits in |value|.
-
- // The bits in the tolerance value. The tolerance value will be
- // sum(bits[width - i] * 2 ^ (- basePrecision - i)) for |i| in
- // range [1, width].
- uint32_t bits;
-};
-
enum class Operation : int {
Abs,
Ceil,
namespace internal {
template <typename T>
-bool compare(Operation op, T input, T libcOutput, const Tolerance &t);
-
-template <typename T>
bool compare(Operation op, T input, T libcOutput, double t);
template <typename T> class MPFRMatcher : public testing::Matcher<T> {
Operation operation;
T input;
- Tolerance tolerance;
T matchValue;
double ulpTolerance;
- bool useULP;
public:
- MPFRMatcher(Operation op, T testInput, Tolerance &t)
- : operation(op), input(testInput), tolerance(t), useULP(false) {}
MPFRMatcher(Operation op, T testInput, double ulpTolerance)
- : operation(op), input(testInput), ulpTolerance(ulpTolerance),
- useULP(true) {}
+ : operation(op), input(testInput), ulpTolerance(ulpTolerance) {}
bool match(T libcResult) {
matchValue = libcResult;
- return (useULP
- ? internal::compare(operation, input, libcResult, ulpTolerance)
- : internal::compare(operation, input, libcResult, tolerance));
+ return internal::compare(operation, input, libcResult, ulpTolerance);
}
void explainError(testutils::StreamWrapper &OS) override;
template <typename T, typename U>
__attribute__((no_sanitize("address")))
-typename cpp::EnableIfType<cpp::IsSameV<U, Tolerance> ||
- cpp::IsSameV<U, double>,
- internal::MPFRMatcher<T>>
+typename cpp::EnableIfType<cpp::IsSameV<U, double>, internal::MPFRMatcher<T>>
getMPFRMatcher(Operation op, T input, U t) {
static_assert(
__llvm_libc::cpp::IsFloatingPointType<T>::Value,