Convert the msun tests to ATF
This provides better error messages that just an assertion failure and also makes it easier to mark individual tests as XFAIL. It was also helpful when coming up with D28786 and D28787. Differential Revision: https://reviews.freebsd.org/D28798
This commit is contained in:
parent
aa05775ef0
commit
133bc64507
@ -52,30 +52,28 @@ NETBSD_ATF_TESTS_C+= sqrt_test
|
||||
NETBSD_ATF_TESTS_C+= tan_test
|
||||
NETBSD_ATF_TESTS_C+= tanh_test
|
||||
|
||||
TAP_TESTS_C+= cexp_test
|
||||
TAP_TESTS_C+= conj_test
|
||||
ATF_TESTS_C+= cexp_test
|
||||
ATF_TESTS_C+= conj_test
|
||||
.if ${MACHINE_CPUARCH} != "aarch64"
|
||||
# Hits an assert in llvm when building for arm64:
|
||||
# https://llvm.org/bugs/show_bug.cgi?id=26081
|
||||
TAP_TESTS_C+= csqrt_test
|
||||
ATF_TESTS_C+= csqrt_test
|
||||
.endif
|
||||
ATF_TESTS_C+= ctrig_test
|
||||
TAP_TESTS_C+= exponential_test
|
||||
TAP_TESTS_C+= fenv_test
|
||||
TAP_TESTS_C+= fma_test
|
||||
TAP_TESTS_C+= fmaxmin_test
|
||||
TAP_TESTS_C+= ilogb2_test
|
||||
TAP_TESTS_C+= invtrig_test
|
||||
TAP_TESTS_C+= invctrig_test
|
||||
TAP_TESTS_C+= logarithm_test
|
||||
TAP_TESTS_C+= lrint_test
|
||||
# XXX: the testcase crashes on all platforms, but only on head
|
||||
# (bug 205451)
|
||||
#TAP_TESTS_C+= lround_test
|
||||
TAP_TESTS_C+= nan_test
|
||||
TAP_TESTS_C+= nearbyint_test
|
||||
TAP_TESTS_C+= next_test
|
||||
TAP_TESTS_C+= rem_test
|
||||
ATF_TESTS_C+= exponential_test
|
||||
ATF_TESTS_C+= fenv_test
|
||||
ATF_TESTS_C+= fma_test
|
||||
ATF_TESTS_C+= fmaxmin_test
|
||||
ATF_TESTS_C+= ilogb2_test
|
||||
ATF_TESTS_C+= invtrig_test
|
||||
ATF_TESTS_C+= invctrig_test
|
||||
ATF_TESTS_C+= logarithm_test
|
||||
ATF_TESTS_C+= lrint_test
|
||||
ATF_TESTS_C+= lround_test
|
||||
ATF_TESTS_C+= nan_test
|
||||
ATF_TESTS_C+= nearbyint_test
|
||||
ATF_TESTS_C+= next_test
|
||||
ATF_TESTS_C+= rem_test
|
||||
ATF_TESTS_C+= trig_test
|
||||
|
||||
.if !empty(PROG) && !empty(TAP_TESTS_C:M${PROG})
|
||||
|
@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <complex.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
@ -63,9 +62,10 @@ __FBSDID("$FreeBSD$");
|
||||
do { \
|
||||
volatile long double complex _d = z; \
|
||||
volatile type complex _r = result; \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(cfpequal_cs((func)(_d), (_r), (checksign))); \
|
||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
ATF_CHECK(cfpequal_cs((func)(_d), (_r), (checksign))); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
|
||||
#func, #z); \
|
||||
} while (0)
|
||||
|
||||
#define test(func, z, result, exceptmask, excepts, checksign) \
|
||||
@ -77,7 +77,7 @@ do { \
|
||||
/* Test within a given tolerance. */
|
||||
#define test_tol(func, z, result, tol) do { \
|
||||
volatile long double complex _d = z; \
|
||||
assert(cfpequal_tol((func)(_d), (result), (tol), \
|
||||
ATF_CHECK(cfpequal_tol((func)(_d), (result), (tol), \
|
||||
FPE_ABS_ZERO | CS_BOTH)); \
|
||||
} while (0)
|
||||
|
||||
@ -102,8 +102,8 @@ static const float finites[] =
|
||||
|
||||
|
||||
/* Tests for 0 */
|
||||
static void
|
||||
test_zero(void)
|
||||
ATF_TC_WITHOUT_HEAD(zero);
|
||||
ATF_TC_BODY(zero, tc)
|
||||
{
|
||||
|
||||
/* cexp(0) = 1, no exceptions raised */
|
||||
@ -117,15 +117,14 @@ test_zero(void)
|
||||
* Tests for NaN. The signs of the results are indeterminate unless the
|
||||
* imaginary part is 0.
|
||||
*/
|
||||
static void
|
||||
test_nan(void)
|
||||
ATF_TC_WITHOUT_HEAD(nan);
|
||||
ATF_TC_BODY(nan, tc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* cexp(x + NaNi) = NaN + NaNi and optionally raises invalid */
|
||||
/* cexp(NaN + yi) = NaN + NaNi and optionally raises invalid (|y|>0) */
|
||||
for (i = 0; i < nitems(finites); i++) {
|
||||
printf("# Run %d..\n", i);
|
||||
testall(CMPLXL(finites[i], NAN), CMPLXL(NAN, NAN),
|
||||
ALL_STD_EXCEPT & ~FE_INVALID, 0, 0);
|
||||
if (finites[i] == 0.0)
|
||||
@ -150,14 +149,13 @@ test_nan(void)
|
||||
ALL_STD_EXCEPT, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_inf(void)
|
||||
ATF_TC_WITHOUT_HEAD(inf);
|
||||
ATF_TC_BODY(inf, tc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/* cexp(x + inf i) = NaN + NaNi and raises invalid */
|
||||
for (i = 0; i < nitems(finites); i++) {
|
||||
printf("# Run %d..\n", i);
|
||||
testall(CMPLXL(finites[i], INFINITY), CMPLXL(NAN, NAN),
|
||||
ALL_STD_EXCEPT, FE_INVALID, 1);
|
||||
}
|
||||
@ -192,14 +190,13 @@ test_inf(void)
|
||||
ALL_STD_EXCEPT, 0, 1);
|
||||
}
|
||||
|
||||
static void
|
||||
test_reals(void)
|
||||
ATF_TC_WITHOUT_HEAD(reals);
|
||||
ATF_TC_BODY(reals, tc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nitems(finites); i++) {
|
||||
/* XXX could check exceptions more meticulously */
|
||||
printf("# Run %d..\n", i);
|
||||
test(cexp, CMPLXL(finites[i], 0.0),
|
||||
CMPLXL(exp(finites[i]), 0.0),
|
||||
FE_INVALID | FE_DIVBYZERO, 0, 1);
|
||||
@ -215,13 +212,12 @@ test_reals(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_imaginaries(void)
|
||||
ATF_TC_WITHOUT_HEAD(imaginaries);
|
||||
ATF_TC_BODY(imaginaries, tc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nitems(finites); i++) {
|
||||
printf("# Run %d..\n", i);
|
||||
test(cexp, CMPLXL(0.0, finites[i]),
|
||||
CMPLXL(cos(finites[i]), sin(finites[i])),
|
||||
ALL_STD_EXCEPT & ~FE_INEXACT, 0, 1);
|
||||
@ -237,8 +233,8 @@ test_imaginaries(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_small(void)
|
||||
ATF_TC_WITHOUT_HEAD(small);
|
||||
ATF_TC_BODY(small, tc)
|
||||
{
|
||||
static const double tests[] = {
|
||||
/* csqrt(a + bI) = x + yI */
|
||||
@ -253,7 +249,6 @@ test_small(void)
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < nitems(tests); i += 4) {
|
||||
printf("# Run %d..\n", i);
|
||||
a = tests[i];
|
||||
b = tests[i + 1];
|
||||
x = tests[i + 2];
|
||||
@ -268,8 +263,8 @@ test_small(void)
|
||||
}
|
||||
|
||||
/* Test inputs with a real part r that would overflow exp(r). */
|
||||
static void
|
||||
test_large(void)
|
||||
ATF_TC_WITHOUT_HEAD(large);
|
||||
ATF_TC_BODY(large, tc)
|
||||
{
|
||||
|
||||
test_tol(cexp, CMPLXL(709.79, 0x1p-1074),
|
||||
@ -295,32 +290,15 @@ test_large(void)
|
||||
CMPLXL(INFINITY, 5.7878851079e+37f), 2 * FLT_ULP());
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, zero);
|
||||
ATF_TP_ADD_TC(tp, nan);
|
||||
ATF_TP_ADD_TC(tp, inf);
|
||||
ATF_TP_ADD_TC(tp, reals);
|
||||
ATF_TP_ADD_TC(tp, imaginaries);
|
||||
ATF_TP_ADD_TC(tp, small);
|
||||
ATF_TP_ADD_TC(tp, large);
|
||||
|
||||
printf("1..7\n");
|
||||
|
||||
test_zero();
|
||||
printf("ok 1 - cexp zero\n");
|
||||
|
||||
test_nan();
|
||||
printf("ok 2 - cexp nan\n");
|
||||
|
||||
test_inf();
|
||||
printf("ok 3 - cexp inf\n");
|
||||
|
||||
test_reals();
|
||||
printf("ok 4 - cexp reals\n");
|
||||
|
||||
test_imaginaries();
|
||||
printf("ok 5 - cexp imaginaries\n");
|
||||
|
||||
test_small();
|
||||
printf("ok 6 - cexp small\n");
|
||||
|
||||
test_large();
|
||||
printf("ok 7 - cexp large\n");
|
||||
|
||||
return (0);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <assert.h>
|
||||
#include <complex.h>
|
||||
#include <fenv.h>
|
||||
#include <math.h>
|
||||
@ -70,70 +69,54 @@ static const double tests[] = {
|
||||
-INFINITY, INFINITY,
|
||||
};
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(main);
|
||||
ATF_TC_BODY(main, tc)
|
||||
{
|
||||
static const int ntests = sizeof(tests) / sizeof(tests[0]) / 2;
|
||||
complex float in;
|
||||
complex long double expected;
|
||||
int i;
|
||||
|
||||
printf("1..%d\n", ntests * 3);
|
||||
|
||||
for (i = 0; i < ntests; i++) {
|
||||
__real__ expected = __real__ in = tests[2 * i];
|
||||
__imag__ in = tests[2 * i + 1];
|
||||
__imag__ expected = -cimag(in);
|
||||
|
||||
assert(fpequal(libcrealf(in), __real__ in));
|
||||
assert(fpequal(libcreal(in), __real__ in));
|
||||
assert(fpequal(libcreall(in), __real__ in));
|
||||
assert(fpequal(libcimagf(in), __imag__ in));
|
||||
assert(fpequal(libcimag(in), __imag__ in));
|
||||
assert(fpequal(libcimagl(in), __imag__ in));
|
||||
ATF_REQUIRE(fpequal(libcrealf(in), __real__ in));
|
||||
ATF_REQUIRE(fpequal(libcreal(in), __real__ in));
|
||||
ATF_REQUIRE(fpequal(libcreall(in), __real__ in));
|
||||
ATF_REQUIRE(fpequal(libcimagf(in), __imag__ in));
|
||||
ATF_REQUIRE(fpequal(libcimag(in), __imag__ in));
|
||||
ATF_REQUIRE(fpequal(libcimagl(in), __imag__ in));
|
||||
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
if (!cfpequal(libconjf(in), expected)) {
|
||||
printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
|
||||
"wrong value\n",
|
||||
3 * i + 1, creal(in), cimag(in));
|
||||
} else if (fetestexcept(FE_ALL_EXCEPT)) {
|
||||
printf("not ok %d\t# conjf(%#.2g + %#.2gI): "
|
||||
"threw an exception\n",
|
||||
3 * i + 1, creal(in), cimag(in));
|
||||
} else {
|
||||
printf("ok %d\t\t# conjf(%#.2g + %#.2gI)\n",
|
||||
3 * i + 1, creal(in), cimag(in));
|
||||
}
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
ATF_REQUIRE_MSG(
|
||||
cfpequal(libconjf(in), expected),
|
||||
"conjf(%#.2g + %#.2gI): wrong value", creal(in), cimag(in)
|
||||
);
|
||||
ATF_REQUIRE_EQ_MSG(0, fetestexcept(FE_ALL_EXCEPT),
|
||||
"conj(%#.2g + %#.2gI): threw an exception: %#x", creal(in),
|
||||
cimag(in), fetestexcept(FE_ALL_EXCEPT));
|
||||
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
if (!cfpequal(libconj(in), expected)) {
|
||||
printf("not ok %d\t# conj(%#.2g + %#.2gI): "
|
||||
"wrong value\n",
|
||||
3 * i + 2, creal(in), cimag(in));
|
||||
} else if (fetestexcept(FE_ALL_EXCEPT)) {
|
||||
printf("not ok %d\t# conj(%#.2g + %#.2gI): "
|
||||
"threw an exception\n",
|
||||
3 * i + 2, creal(in), cimag(in));
|
||||
} else {
|
||||
printf("ok %d\t\t# conj(%#.2g + %#.2gI)\n",
|
||||
3 * i + 2, creal(in), cimag(in));
|
||||
}
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
ATF_REQUIRE_MSG(cfpequal(libconj(in), expected),
|
||||
"conj(%#.2g + %#.2gI): wrong value", creal(in), cimag(in));
|
||||
ATF_REQUIRE_EQ_MSG(0, fetestexcept(FE_ALL_EXCEPT),
|
||||
"conj(%#.2g + %#.2gI): threw an exception: %#x", creal(in),
|
||||
cimag(in), fetestexcept(FE_ALL_EXCEPT));
|
||||
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
if (!cfpequal(libconjl(in), expected)) {
|
||||
printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
|
||||
"wrong value\n",
|
||||
3 * i + 3, creal(in), cimag(in));
|
||||
} else if (fetestexcept(FE_ALL_EXCEPT)) {
|
||||
printf("not ok %d\t# conjl(%#.2g + %#.2gI): "
|
||||
"threw an exception\n",
|
||||
3 * i + 3, creal(in), cimag(in));
|
||||
} else {
|
||||
printf("ok %d\t\t# conjl(%#.2g + %#.2gI)\n",
|
||||
3 * i + 3, creal(in), cimag(in));
|
||||
}
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
ATF_REQUIRE_MSG(cfpequal(libconjl(in), expected),
|
||||
"conjl(%#.2g + %#.2gI): wrong value", creal(in), cimag(in));
|
||||
ATF_REQUIRE_EQ_MSG(0, fetestexcept(FE_ALL_EXCEPT),
|
||||
"conjl(%#.2g + %#.2gI): threw an exception: %#x", creal(in),
|
||||
cimag(in), fetestexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, main);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -33,7 +33,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <complex.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -72,7 +71,7 @@ static void
|
||||
assert_equal(long double complex d1, long double complex d2)
|
||||
{
|
||||
|
||||
assert(cfpequal(d1, d2));
|
||||
ATF_CHECK(cfpequal(d1, d2));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -133,7 +132,7 @@ test_finite(void)
|
||||
b = tests[i + 1] * mults[j] * mults[j];
|
||||
x = tests[i + 2] * mults[j];
|
||||
y = tests[i + 3] * mults[j];
|
||||
assert(t_csqrt(CMPLXL(a, b)) == CMPLXL(x, y));
|
||||
ATF_CHECK(t_csqrt(CMPLXL(a, b)) == CMPLXL(x, y));
|
||||
}
|
||||
}
|
||||
|
||||
@ -190,11 +189,11 @@ static void
|
||||
test_nans(void)
|
||||
{
|
||||
|
||||
assert(creall(t_csqrt(CMPLXL(INFINITY, NAN))) == INFINITY);
|
||||
assert(isnan(cimagl(t_csqrt(CMPLXL(INFINITY, NAN)))));
|
||||
ATF_CHECK(creall(t_csqrt(CMPLXL(INFINITY, NAN))) == INFINITY);
|
||||
ATF_CHECK(isnan(cimagl(t_csqrt(CMPLXL(INFINITY, NAN)))));
|
||||
|
||||
assert(isnan(creall(t_csqrt(CMPLXL(-INFINITY, NAN)))));
|
||||
assert(isinf(cimagl(t_csqrt(CMPLXL(-INFINITY, NAN)))));
|
||||
ATF_CHECK(isnan(creall(t_csqrt(CMPLXL(-INFINITY, NAN)))));
|
||||
ATF_CHECK(isinf(cimagl(t_csqrt(CMPLXL(-INFINITY, NAN)))));
|
||||
|
||||
assert_equal(t_csqrt(CMPLXL(NAN, INFINITY)),
|
||||
CMPLXL(INFINITY, INFINITY));
|
||||
@ -224,7 +223,7 @@ test_overflow(int maxexp)
|
||||
long double complex result;
|
||||
int exp, i;
|
||||
|
||||
assert(maxexp > 0 && maxexp % 2 == 0);
|
||||
ATF_CHECK(maxexp > 0 && maxexp % 2 == 0);
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
exp = maxexp - 2 * i;
|
||||
@ -233,22 +232,22 @@ test_overflow(int maxexp)
|
||||
a = ldexpl(115 * 0x1p-8, exp);
|
||||
b = ldexpl(252 * 0x1p-8, exp);
|
||||
result = t_csqrt(CMPLXL(a, b));
|
||||
assert(creall(result) == ldexpl(14 * 0x1p-4, exp / 2));
|
||||
assert(cimagl(result) == ldexpl(9 * 0x1p-4, exp / 2));
|
||||
ATF_CHECK_EQ(creall(result), ldexpl(14 * 0x1p-4, exp / 2));
|
||||
ATF_CHECK_EQ(cimagl(result), ldexpl(9 * 0x1p-4, exp / 2));
|
||||
|
||||
/* csqrt(-11 + 60*I) = 5 + 6*I */
|
||||
a = ldexpl(-11 * 0x1p-6, exp);
|
||||
b = ldexpl(60 * 0x1p-6, exp);
|
||||
result = t_csqrt(CMPLXL(a, b));
|
||||
assert(creall(result) == ldexpl(5 * 0x1p-3, exp / 2));
|
||||
assert(cimagl(result) == ldexpl(6 * 0x1p-3, exp / 2));
|
||||
ATF_CHECK_EQ(creall(result), ldexpl(5 * 0x1p-3, exp / 2));
|
||||
ATF_CHECK_EQ(cimagl(result), ldexpl(6 * 0x1p-3, exp / 2));
|
||||
|
||||
/* csqrt(225 + 0*I) == 15 + 0*I */
|
||||
a = ldexpl(225 * 0x1p-8, exp);
|
||||
b = 0;
|
||||
result = t_csqrt(CMPLXL(a, b));
|
||||
assert(creall(result) == ldexpl(15 * 0x1p-4, exp / 2));
|
||||
assert(cimagl(result) == 0);
|
||||
ATF_CHECK_EQ(creall(result), ldexpl(15 * 0x1p-4, exp / 2));
|
||||
ATF_CHECK_EQ(cimagl(result), 0);
|
||||
}
|
||||
}
|
||||
|
||||
@ -266,8 +265,8 @@ test_precision(int maxexp, int mantdig)
|
||||
uint64_t mantbits, sq_mantbits;
|
||||
int exp, i;
|
||||
|
||||
assert(maxexp > 0 && maxexp % 2 == 0);
|
||||
assert(mantdig <= 64);
|
||||
ATF_CHECK(maxexp > 0 && maxexp % 2 == 0);
|
||||
ATF_CHECK(mantdig <= 64);
|
||||
mantdig = rounddown(mantdig, 2);
|
||||
|
||||
for (exp = 0; exp <= maxexp; exp += 2) {
|
||||
@ -289,79 +288,67 @@ test_precision(int maxexp, int mantdig)
|
||||
b = ldexpl((long double)sq_mantbits,
|
||||
exp - 1 - mantdig);
|
||||
x = ldexpl(mantbits, (exp - 2 - mantdig) / 2);
|
||||
assert(b == x * x * 2);
|
||||
ATF_CHECK_EQ(b, x * x * 2);
|
||||
result = t_csqrt(CMPLXL(0, b));
|
||||
assert(creall(result) == x);
|
||||
assert(cimagl(result) == x);
|
||||
ATF_CHECK_EQ(x, creall(result));
|
||||
ATF_CHECK_EQ(x, cimagl(result));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(csqrt);
|
||||
ATF_TC_BODY(csqrt, tc)
|
||||
{
|
||||
|
||||
printf("1..18\n");
|
||||
|
||||
/* Test csqrt() */
|
||||
t_csqrt = _csqrt;
|
||||
|
||||
test_finite();
|
||||
printf("ok 1 - csqrt\n");
|
||||
|
||||
test_zeros();
|
||||
printf("ok 2 - csqrt\n");
|
||||
|
||||
test_infinities();
|
||||
printf("ok 3 - csqrt\n");
|
||||
|
||||
test_nans();
|
||||
printf("ok 4 - csqrt\n");
|
||||
|
||||
test_overflow(DBL_MAX_EXP);
|
||||
printf("ok 5 - csqrt\n");
|
||||
|
||||
test_precision(DBL_MAX_EXP, DBL_MANT_DIG);
|
||||
printf("ok 6 - csqrt\n");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(csqrtf);
|
||||
ATF_TC_BODY(csqrtf, tc)
|
||||
{
|
||||
/* Now test csqrtf() */
|
||||
t_csqrt = _csqrtf;
|
||||
|
||||
test_finite();
|
||||
printf("ok 7 - csqrt\n");
|
||||
|
||||
test_zeros();
|
||||
printf("ok 8 - csqrt\n");
|
||||
|
||||
test_infinities();
|
||||
printf("ok 9 - csqrt\n");
|
||||
|
||||
test_nans();
|
||||
printf("ok 10 - csqrt\n");
|
||||
|
||||
test_overflow(FLT_MAX_EXP);
|
||||
printf("ok 11 - csqrt\n");
|
||||
|
||||
test_precision(FLT_MAX_EXP, FLT_MANT_DIG);
|
||||
printf("ok 12 - csqrt\n");
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(csqrtl);
|
||||
ATF_TC_BODY(csqrtl, tc)
|
||||
{
|
||||
/* Now test csqrtl() */
|
||||
t_csqrt = csqrtl;
|
||||
|
||||
test_finite();
|
||||
printf("ok 13 - csqrt\n");
|
||||
|
||||
test_zeros();
|
||||
printf("ok 14 - csqrt\n");
|
||||
|
||||
test_infinities();
|
||||
printf("ok 15 - csqrt\n");
|
||||
|
||||
test_nans();
|
||||
printf("ok 16 - csqrt\n");
|
||||
|
||||
test_overflow(LDBL_MAX_EXP);
|
||||
printf("ok 17 - csqrt\n");
|
||||
|
||||
test_precision(LDBL_MAX_EXP,
|
||||
#ifndef __i386__
|
||||
@ -370,7 +357,13 @@ main(void)
|
||||
DBL_MANT_DIG
|
||||
#endif
|
||||
);
|
||||
printf("ok 18 - csqrt\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, csqrt);
|
||||
ATF_TP_ADD_TC(tp, csqrtf);
|
||||
ATF_TP_ADD_TC(tp, csqrtl);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -38,8 +38,6 @@ __FBSDID("$FreeBSD$");
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -60,9 +59,10 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#define test(func, x, result, exceptmask, excepts) do { \
|
||||
volatile long double _d = x; \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(fpequal((func)(_d), (result))); \
|
||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
ATF_CHECK(fpequal((func)(_d), (result))); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
} while (0)
|
||||
|
||||
/* Test all the functions that compute b^x. */
|
||||
@ -122,48 +122,66 @@ run_generic_tests(void)
|
||||
testall1(-50000.0, -1.0, ALL_STD_EXCEPT, FE_INEXACT);
|
||||
}
|
||||
|
||||
static void
|
||||
run_exp2_tests(void)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
/*
|
||||
* We should insist that exp2() return exactly the correct
|
||||
* result and not raise an inexact exception for integer
|
||||
* arguments.
|
||||
*/
|
||||
feclearexcept(FE_ALL_EXCEPT);
|
||||
for (i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) {
|
||||
assert(exp2f(i) == ldexpf(1.0, i));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
}
|
||||
for (i = DBL_MIN_EXP - DBL_MANT_DIG; i < DBL_MAX_EXP; i++) {
|
||||
assert(exp2(i) == ldexp(1.0, i));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
}
|
||||
for (i = LDBL_MIN_EXP - LDBL_MANT_DIG; i < LDBL_MAX_EXP; i++) {
|
||||
assert(exp2l(i) == ldexpl(1.0, i));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
/*
|
||||
* We should insist that exp2() return exactly the correct
|
||||
* result and not raise an inexact exception for integer
|
||||
* arguments.
|
||||
*/
|
||||
ATF_TC_WITHOUT_HEAD(exp2f);
|
||||
ATF_TC_BODY(exp2f, tc)
|
||||
{
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
for (int i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) {
|
||||
ATF_CHECK_EQ(exp2f(i), ldexpf(1.0, i));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(exp2);
|
||||
ATF_TC_BODY(exp2, tc)
|
||||
{
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
for (int i = DBL_MIN_EXP - DBL_MANT_DIG; i < DBL_MAX_EXP; i++) {
|
||||
ATF_CHECK_EQ(exp2(i), ldexp(1.0, i));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
printf("1..3\n");
|
||||
ATF_TC_WITHOUT_HEAD(exp2l);
|
||||
ATF_TC_BODY(exp2l, tc)
|
||||
{
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
for (int i = LDBL_MIN_EXP - LDBL_MANT_DIG; i < LDBL_MAX_EXP; i++) {
|
||||
ATF_CHECK_EQ(exp2l(i), ldexpl(1.0, i));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(generic);
|
||||
ATF_TC_BODY(generic, tc)
|
||||
{
|
||||
run_generic_tests();
|
||||
printf("ok 1 - exponential\n");
|
||||
}
|
||||
|
||||
#ifdef __i386__
|
||||
ATF_TC_WITHOUT_HEAD(generic_fp_pe);
|
||||
ATF_TC_BODY(generic_fp_pe, tc)
|
||||
{
|
||||
fpsetprec(FP_PE);
|
||||
run_generic_tests();
|
||||
#endif
|
||||
printf("ok 2 - exponential\n");
|
||||
|
||||
run_exp2_tests();
|
||||
printf("ok 3 - exponential\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, generic);
|
||||
#ifdef __i386__
|
||||
ATF_TP_ADD_TC(tp, generic_fp_pe);
|
||||
#endif
|
||||
ATF_TP_ADD_TC(tp, exp2);
|
||||
ATF_TP_ADD_TC(tp, exp2f);
|
||||
ATF_TP_ADD_TC(tp, exp2l);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -63,11 +63,14 @@ static int std_except_sets[1 << NEXCEPTS];
|
||||
/*
|
||||
* Initialize std_except_sets[] to the power set of std_excepts[]
|
||||
*/
|
||||
static void
|
||||
init_exceptsets(void)
|
||||
static __attribute__((constructor)) void
|
||||
do_setup(void)
|
||||
{
|
||||
unsigned i, j, sr;
|
||||
|
||||
/* Avoid double output after fork() */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
|
||||
for (i = 0; i < 1 << NEXCEPTS; i++) {
|
||||
for (sr = i, j = 0; sr != 0; sr >>= 1, j++)
|
||||
std_except_sets[i] |= std_excepts[j] & ((~sr & 1) - 1);
|
||||
@ -154,7 +157,7 @@ static void
|
||||
trap_handler(int sig)
|
||||
{
|
||||
|
||||
assert(sig == SIGFPE);
|
||||
ATF_CHECK_EQ(SIGFPE, sig);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
@ -163,8 +166,8 @@ trap_handler(int sig)
|
||||
* The memcmp() test below may be too much to ask for, since there
|
||||
* could be multiple machine-specific default environments.
|
||||
*/
|
||||
static void
|
||||
test_dfl_env(void)
|
||||
ATF_TC_WITHOUT_HEAD(dfl_env);
|
||||
ATF_TC_BODY(dfl_env, tc)
|
||||
{
|
||||
#ifndef NO_STRICT_DFL_ENV
|
||||
fenv_t env;
|
||||
@ -186,52 +189,51 @@ test_dfl_env(void)
|
||||
* 1. http://support.amd.com/TechDocs/26569_APM_v5.pdf
|
||||
* 2. http://www.intel.com/Assets/en_US/PDF/manual/253666.pdf
|
||||
*/
|
||||
assert(memcmp(&env.__mxcsr, &FE_DFL_ENV->__mxcsr,
|
||||
ATF_CHECK(memcmp(&env.__mxcsr, &FE_DFL_ENV->__mxcsr,
|
||||
sizeof(env.__mxcsr)) == 0);
|
||||
assert(memcmp(&env.__x87.__control, &FE_DFL_ENV->__x87.__control,
|
||||
ATF_CHECK(memcmp(&env.__x87.__control, &FE_DFL_ENV->__x87.__control,
|
||||
sizeof(env.__x87.__control)) == 0);
|
||||
assert(memcmp(&env.__x87.__status, &FE_DFL_ENV->__x87.__status,
|
||||
ATF_CHECK(memcmp(&env.__x87.__status, &FE_DFL_ENV->__x87.__status,
|
||||
sizeof(env.__x87.__status)) == 0);
|
||||
assert(memcmp(&env.__x87.__tag, &FE_DFL_ENV->__x87.__tag,
|
||||
ATF_CHECK(memcmp(&env.__x87.__tag, &FE_DFL_ENV->__x87.__tag,
|
||||
sizeof(env.__x87.__tag)) == 0);
|
||||
#else
|
||||
assert(memcmp(&env, FE_DFL_ENV, sizeof(env)) == 0);
|
||||
ATF_CHECK_EQ(0, memcmp(&env, FE_DFL_ENV, sizeof(env)));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test fetestexcept() and feclearexcept().
|
||||
*/
|
||||
static void
|
||||
test_fetestclearexcept(void)
|
||||
ATF_TC_WITHOUT_HEAD(fetestclearexcept);
|
||||
ATF_TC_BODY(fetestclearexcept, tc)
|
||||
{
|
||||
int excepts, i;
|
||||
|
||||
for (i = 0; i < 1 << NEXCEPTS; i++)
|
||||
assert(fetestexcept(std_except_sets[i]) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(std_except_sets[i]));
|
||||
for (i = 0; i < 1 << NEXCEPTS; i++) {
|
||||
excepts = std_except_sets[i];
|
||||
|
||||
/* FE_ALL_EXCEPT might be special-cased, as on i386. */
|
||||
raiseexcept(excepts);
|
||||
assert(fetestexcept(excepts) == excepts);
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(excepts, fetestexcept(excepts));
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
|
||||
raiseexcept(excepts);
|
||||
assert(fetestexcept(excepts) == excepts);
|
||||
ATF_CHECK_EQ(excepts, fetestexcept(excepts));
|
||||
if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0) {
|
||||
excepts |= FE_INEXACT;
|
||||
assert((fetestexcept(ALL_STD_EXCEPT) | FE_INEXACT) ==
|
||||
excepts);
|
||||
ATF_CHECK_EQ(excepts, (fetestexcept(ALL_STD_EXCEPT) | FE_INEXACT));
|
||||
} else {
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == excepts);
|
||||
ATF_CHECK_EQ(excepts, fetestexcept(ALL_STD_EXCEPT));
|
||||
}
|
||||
assert(feclearexcept(excepts) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, feclearexcept(excepts));
|
||||
ATF_CHECK_EQ(0, fetestexcept(ALL_STD_EXCEPT));
|
||||
}
|
||||
}
|
||||
|
||||
@ -240,31 +242,29 @@ test_fetestclearexcept(void)
|
||||
*
|
||||
* Prerequisites: fetestexcept(), feclearexcept()
|
||||
*/
|
||||
static void
|
||||
test_fegsetexceptflag(void)
|
||||
ATF_TC_WITHOUT_HEAD(fegsetexceptflag);
|
||||
ATF_TC_BODY(fegsetexceptflag, tc)
|
||||
{
|
||||
fexcept_t flag;
|
||||
int excepts, i;
|
||||
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
for (i = 0; i < 1 << NEXCEPTS; i++) {
|
||||
excepts = std_except_sets[i];
|
||||
|
||||
assert(fegetexceptflag(&flag, excepts) == 0);
|
||||
ATF_CHECK_EQ(0, fegetexceptflag(&flag, excepts));
|
||||
raiseexcept(ALL_STD_EXCEPT);
|
||||
assert(fesetexceptflag(&flag, excepts) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) ==
|
||||
(ALL_STD_EXCEPT ^ excepts));
|
||||
ATF_CHECK_EQ(0, fesetexceptflag(&flag, excepts));
|
||||
ATF_CHECK_EQ((ALL_STD_EXCEPT ^ excepts), fetestexcept(ALL_STD_EXCEPT));
|
||||
|
||||
assert(fegetexceptflag(&flag, FE_ALL_EXCEPT) == 0);
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(fesetexceptflag(&flag, excepts) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
assert(fesetexceptflag(&flag, ALL_STD_EXCEPT ^ excepts) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) ==
|
||||
(ALL_STD_EXCEPT ^ excepts));
|
||||
ATF_CHECK_EQ(0, fegetexceptflag(&flag, FE_ALL_EXCEPT));
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
ATF_CHECK_EQ(0, fesetexceptflag(&flag, excepts));
|
||||
ATF_CHECK_EQ(0, fetestexcept(ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ(0, fesetexceptflag(&flag, ALL_STD_EXCEPT ^ excepts));
|
||||
ATF_CHECK_EQ((ALL_STD_EXCEPT ^ excepts), fetestexcept(ALL_STD_EXCEPT));
|
||||
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,63 +273,62 @@ test_fegsetexceptflag(void)
|
||||
*
|
||||
* Prerequisites: fetestexcept(), feclearexcept()
|
||||
*/
|
||||
static void
|
||||
test_feraiseexcept(void)
|
||||
ATF_TC_WITHOUT_HEAD(feraiseexcept);
|
||||
ATF_TC_BODY(feraiseexcept, tc)
|
||||
{
|
||||
int excepts, i;
|
||||
|
||||
for (i = 0; i < 1 << NEXCEPTS; i++) {
|
||||
excepts = std_except_sets[i];
|
||||
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(feraiseexcept(excepts) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
ATF_CHECK_EQ(0, feraiseexcept(excepts));
|
||||
if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0) {
|
||||
excepts |= FE_INEXACT;
|
||||
assert((fetestexcept(ALL_STD_EXCEPT) | FE_INEXACT) ==
|
||||
excepts);
|
||||
ATF_CHECK_EQ(excepts, (fetestexcept(ALL_STD_EXCEPT) | FE_INEXACT));
|
||||
} else {
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == excepts);
|
||||
ATF_CHECK_EQ(excepts, fetestexcept(ALL_STD_EXCEPT));
|
||||
}
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
assert(feraiseexcept(FE_INVALID | FE_DIVBYZERO) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == (FE_INVALID | FE_DIVBYZERO));
|
||||
assert(feraiseexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == ALL_STD_EXCEPT);
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, feraiseexcept(FE_INVALID | FE_DIVBYZERO));
|
||||
ATF_CHECK_EQ((FE_INVALID | FE_DIVBYZERO), fetestexcept(ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ(0, feraiseexcept(FE_OVERFLOW | FE_UNDERFLOW | FE_INEXACT));
|
||||
ATF_CHECK_EQ(ALL_STD_EXCEPT, fetestexcept(ALL_STD_EXCEPT));
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
|
||||
/*
|
||||
* Test fegetround() and fesetround().
|
||||
*/
|
||||
static void
|
||||
test_fegsetround(void)
|
||||
ATF_TC_WITHOUT_HEAD(fegsetround);
|
||||
ATF_TC_BODY(fegsetround, tc)
|
||||
{
|
||||
|
||||
assert(fegetround() == FE_TONEAREST);
|
||||
assert(getround() == FE_TONEAREST);
|
||||
assert(FLT_ROUNDS == 1);
|
||||
ATF_CHECK_EQ(FE_TONEAREST, fegetround());
|
||||
ATF_CHECK_EQ(FE_TONEAREST, getround());
|
||||
ATF_CHECK_EQ(1, FLT_ROUNDS);
|
||||
|
||||
assert(fesetround(FE_DOWNWARD) == 0);
|
||||
assert(fegetround() == FE_DOWNWARD);
|
||||
assert(getround() == FE_DOWNWARD);
|
||||
assert(FLT_ROUNDS == 3);
|
||||
ATF_CHECK_EQ(0, fesetround(FE_DOWNWARD));
|
||||
ATF_CHECK_EQ(FE_DOWNWARD, fegetround());
|
||||
ATF_CHECK_EQ(FE_DOWNWARD, getround());
|
||||
ATF_CHECK_EQ(3, FLT_ROUNDS);
|
||||
|
||||
assert(fesetround(FE_UPWARD) == 0);
|
||||
assert(getround() == FE_UPWARD);
|
||||
assert(fegetround() == FE_UPWARD);
|
||||
assert(FLT_ROUNDS == 2);
|
||||
ATF_CHECK_EQ(0, fesetround(FE_UPWARD));
|
||||
ATF_CHECK_EQ(FE_UPWARD, getround());
|
||||
ATF_CHECK_EQ(FE_UPWARD, fegetround());
|
||||
ATF_CHECK_EQ(2, FLT_ROUNDS);
|
||||
|
||||
assert(fesetround(FE_TOWARDZERO) == 0);
|
||||
assert(getround() == FE_TOWARDZERO);
|
||||
assert(fegetround() == FE_TOWARDZERO);
|
||||
assert(FLT_ROUNDS == 0);
|
||||
ATF_CHECK_EQ(0, fesetround(FE_TOWARDZERO));
|
||||
ATF_CHECK_EQ(FE_TOWARDZERO, getround());
|
||||
ATF_CHECK_EQ(FE_TOWARDZERO, fegetround());
|
||||
ATF_CHECK_EQ(0, FLT_ROUNDS);
|
||||
|
||||
assert(fesetround(FE_TONEAREST) == 0);
|
||||
assert(getround() == FE_TONEAREST);
|
||||
assert(FLT_ROUNDS == 1);
|
||||
ATF_CHECK_EQ(0, fesetround(FE_TONEAREST));
|
||||
ATF_CHECK_EQ(FE_TONEAREST, getround());
|
||||
ATF_CHECK_EQ(1, FLT_ROUNDS);
|
||||
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -337,8 +336,8 @@ test_fegsetround(void)
|
||||
*
|
||||
* Prerequisites: fetestexcept(), feclearexcept(), fegetround(), fesetround()
|
||||
*/
|
||||
static void
|
||||
test_fegsetenv(void)
|
||||
ATF_TC_WITHOUT_HEAD(fegsetenv);
|
||||
ATF_TC_BODY(fegsetenv, tc)
|
||||
{
|
||||
fenv_t env1, env2;
|
||||
int excepts, i;
|
||||
@ -346,9 +345,9 @@ test_fegsetenv(void)
|
||||
for (i = 0; i < 1 << NEXCEPTS; i++) {
|
||||
excepts = std_except_sets[i];
|
||||
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(fegetround() == FE_TONEAREST);
|
||||
assert(fegetenv(&env1) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
ATF_CHECK_EQ(FE_TONEAREST, fegetround());
|
||||
ATF_CHECK_EQ(0, fegetenv(&env1));
|
||||
|
||||
/*
|
||||
* fe[gs]etenv() should be able to save and restore
|
||||
@ -358,26 +357,26 @@ test_fegsetenv(void)
|
||||
raiseexcept(excepts);
|
||||
if ((excepts & (FE_UNDERFLOW | FE_OVERFLOW)) != 0 &&
|
||||
(excepts & FE_INEXACT) == 0)
|
||||
assert(feclearexcept(FE_INEXACT) == 0);
|
||||
ATF_CHECK_EQ(0, feclearexcept(FE_INEXACT));
|
||||
|
||||
fesetround(FE_DOWNWARD);
|
||||
assert(fegetenv(&env2) == 0);
|
||||
assert(fesetenv(&env1) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(fegetround() == FE_TONEAREST);
|
||||
ATF_CHECK_EQ(0, fegetenv(&env2));
|
||||
ATF_CHECK_EQ(0, fesetenv(&env1));
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
ATF_CHECK_EQ(FE_TONEAREST, fegetround());
|
||||
|
||||
assert(fesetenv(&env2) == 0);
|
||||
ATF_CHECK_EQ(0, fesetenv(&env2));
|
||||
|
||||
/*
|
||||
* Some platforms like powerpc may set extra exception bits. Since
|
||||
* only standard exceptions are tested, mask against ALL_STD_EXCEPT
|
||||
*/
|
||||
assert((fetestexcept(FE_ALL_EXCEPT) & ALL_STD_EXCEPT) == excepts);
|
||||
ATF_CHECK_EQ(excepts, (fetestexcept(FE_ALL_EXCEPT) & ALL_STD_EXCEPT));
|
||||
|
||||
assert(fegetround() == FE_DOWNWARD);
|
||||
assert(fesetenv(&env1) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
assert(fegetround() == FE_TONEAREST);
|
||||
ATF_CHECK_EQ(FE_DOWNWARD, fegetround());
|
||||
ATF_CHECK_EQ(0, fesetenv(&env1));
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
ATF_CHECK_EQ(FE_TONEAREST, fegetround());
|
||||
}
|
||||
}
|
||||
|
||||
@ -386,23 +385,20 @@ test_fegsetenv(void)
|
||||
*
|
||||
* Prerequisites: fetestexcept(), feraiseexcept()
|
||||
*/
|
||||
static void
|
||||
test_masking(void)
|
||||
ATF_TC_WITHOUT_HEAD(masking);
|
||||
ATF_TC_BODY(masking, tc)
|
||||
{
|
||||
struct sigaction act;
|
||||
int except, pass, raise, status;
|
||||
unsigned i;
|
||||
|
||||
assert((fegetexcept() & ALL_STD_EXCEPT) == 0);
|
||||
assert((feenableexcept(FE_INVALID|FE_OVERFLOW) & ALL_STD_EXCEPT) == 0);
|
||||
assert((feenableexcept(FE_UNDERFLOW) & ALL_STD_EXCEPT) ==
|
||||
(FE_INVALID | FE_OVERFLOW));
|
||||
assert((fedisableexcept(FE_OVERFLOW) & ALL_STD_EXCEPT) ==
|
||||
(FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW));
|
||||
assert((fegetexcept() & ALL_STD_EXCEPT) == (FE_INVALID | FE_UNDERFLOW));
|
||||
assert((fedisableexcept(FE_ALL_EXCEPT) & ALL_STD_EXCEPT) ==
|
||||
(FE_INVALID | FE_UNDERFLOW));
|
||||
assert((fegetexcept() & ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, (fegetexcept() & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ(0, (feenableexcept(FE_INVALID|FE_OVERFLOW) & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ((FE_INVALID | FE_OVERFLOW), (feenableexcept(FE_UNDERFLOW) & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ((FE_INVALID | FE_OVERFLOW | FE_UNDERFLOW), (fedisableexcept(FE_OVERFLOW) & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ((FE_INVALID | FE_UNDERFLOW), (fegetexcept() & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ((FE_INVALID | FE_UNDERFLOW), (fedisableexcept(FE_ALL_EXCEPT) & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ(0, (fegetexcept() & ALL_STD_EXCEPT));
|
||||
|
||||
sigemptyset(&act.sa_mask);
|
||||
act.sa_flags = 0;
|
||||
@ -423,40 +419,39 @@ test_masking(void)
|
||||
*/
|
||||
switch(fork()) {
|
||||
case 0: /* child */
|
||||
assert((fegetexcept() & ALL_STD_EXCEPT) == 0);
|
||||
assert((feenableexcept(except)
|
||||
& ALL_STD_EXCEPT) == 0);
|
||||
assert(fegetexcept() == except);
|
||||
ATF_CHECK_EQ(0, (fegetexcept() & ALL_STD_EXCEPT));
|
||||
ATF_REQUIRE_EQ(0, (feenableexcept(except) & ALL_STD_EXCEPT));
|
||||
ATF_CHECK_EQ(except, fegetexcept());
|
||||
raiseexcept(raise);
|
||||
assert(feraiseexcept(raise) == 0);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == raise);
|
||||
ATF_CHECK_EQ(0, feraiseexcept(raise));
|
||||
ATF_CHECK_EQ(raise, fetestexcept(ALL_STD_EXCEPT));
|
||||
|
||||
assert(sigaction(SIGFPE, &act, NULL) == 0);
|
||||
ATF_CHECK_EQ(0, sigaction(SIGFPE, &act, NULL));
|
||||
switch (pass) {
|
||||
case 0:
|
||||
raiseexcept(except);
|
||||
case 1:
|
||||
feraiseexcept(except);
|
||||
default:
|
||||
assert(0);
|
||||
ATF_REQUIRE(0);
|
||||
}
|
||||
assert(0);
|
||||
ATF_REQUIRE(0);
|
||||
default: /* parent */
|
||||
assert(wait(&status) > 0);
|
||||
ATF_REQUIRE(wait(&status) > 0);
|
||||
/*
|
||||
* Avoid assert() here so that it's possible
|
||||
* to examine a failed child's core dump.
|
||||
*/
|
||||
if (!WIFEXITED(status))
|
||||
errx(1, "child aborted\n");
|
||||
assert(WEXITSTATUS(status) == 0);
|
||||
ATF_CHECK_EQ(0, WEXITSTATUS(status));
|
||||
break;
|
||||
case -1: /* error */
|
||||
assert(0);
|
||||
ATF_REQUIRE(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
|
||||
/*
|
||||
@ -465,8 +460,8 @@ test_masking(void)
|
||||
* Prerequisites: fetestexcept(), fegetround(), fesetround(),
|
||||
* fedisableexcept(), feenableexcept()
|
||||
*/
|
||||
static void
|
||||
test_feholdupdate(void)
|
||||
ATF_TC_WITHOUT_HEAD(feholdupdate);
|
||||
ATF_TC_BODY(feholdupdate, tc)
|
||||
{
|
||||
fenv_t env;
|
||||
|
||||
@ -499,67 +494,50 @@ test_feholdupdate(void)
|
||||
* check other properties of feupdateenv().
|
||||
*/
|
||||
if (pass == 1)
|
||||
assert((feenableexcept(except) &
|
||||
ALL_STD_EXCEPT) == 0);
|
||||
ATF_REQUIRE_EQ(0, feenableexcept(except) & ALL_STD_EXCEPT);
|
||||
raiseexcept(raise);
|
||||
assert(fesetround(FE_DOWNWARD) == 0);
|
||||
assert(feholdexcept(&env) == 0);
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, fesetround(FE_DOWNWARD));
|
||||
ATF_CHECK_EQ(0, feholdexcept(&env));
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
raiseexcept(except);
|
||||
assert(fesetround(FE_UPWARD) == 0);
|
||||
ATF_CHECK_EQ(0, fesetround(FE_UPWARD));
|
||||
|
||||
if (pass == 1)
|
||||
assert(sigaction(SIGFPE, &act, NULL) ==
|
||||
0);
|
||||
assert(feupdateenv(&env) == 0);
|
||||
assert(fegetround() == FE_DOWNWARD);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) ==
|
||||
(except | raise));
|
||||
ATF_CHECK_EQ(0, sigaction(SIGFPE, &act, NULL));
|
||||
ATF_CHECK_EQ(0, feupdateenv(&env));
|
||||
ATF_CHECK_EQ(FE_DOWNWARD, fegetround());
|
||||
ATF_CHECK_EQ((except | raise), fetestexcept(ALL_STD_EXCEPT));
|
||||
|
||||
assert(pass == 0);
|
||||
ATF_CHECK_EQ(0, pass);
|
||||
_exit(0);
|
||||
default: /* parent */
|
||||
assert(wait(&status) > 0);
|
||||
ATF_REQUIRE(wait(&status) > 0);
|
||||
/*
|
||||
* Avoid assert() here so that it's possible
|
||||
* to examine a failed child's core dump.
|
||||
*/
|
||||
if (!WIFEXITED(status))
|
||||
errx(1, "child aborted\n");
|
||||
assert(WEXITSTATUS(status) == 0);
|
||||
ATF_CHECK_EQ(0, WEXITSTATUS(status));
|
||||
break;
|
||||
case -1: /* error */
|
||||
assert(0);
|
||||
ATF_REQUIRE(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT));
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
/* Avoid double output after fork() */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
ATF_TP_ADD_TC(tp, dfl_env);
|
||||
ATF_TP_ADD_TC(tp, fetestclearexcept);
|
||||
ATF_TP_ADD_TC(tp, fegsetexceptflag);
|
||||
ATF_TP_ADD_TC(tp, feraiseexcept);
|
||||
ATF_TP_ADD_TC(tp, fegsetround);
|
||||
ATF_TP_ADD_TC(tp, fegsetenv);
|
||||
ATF_TP_ADD_TC(tp, masking);
|
||||
ATF_TP_ADD_TC(tp, feholdupdate);
|
||||
|
||||
printf("1..8\n");
|
||||
init_exceptsets();
|
||||
test_dfl_env();
|
||||
printf("ok 1 - fenv\n");
|
||||
test_fetestclearexcept();
|
||||
printf("ok 2 - fenv\n");
|
||||
test_fegsetexceptflag();
|
||||
printf("ok 3 - fenv\n");
|
||||
test_feraiseexcept();
|
||||
printf("ok 4 - fenv\n");
|
||||
test_fegsetround();
|
||||
printf("ok 5 - fenv\n");
|
||||
test_fegsetenv();
|
||||
printf("ok 6 - fenv\n");
|
||||
test_masking();
|
||||
printf("ok 7 - fenv\n");
|
||||
test_feholdupdate();
|
||||
printf("ok 8 - fenv\n");
|
||||
|
||||
return (0);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -55,9 +54,10 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#define test(func, x, y, z, result, exceptmask, excepts) do { \
|
||||
volatile long double _vx = (x), _vy = (y), _vz = (z); \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(fpequal((func)(_vx, _vy, _vz), (result))); \
|
||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
ATF_CHECK(fpequal((func)(_vx, _vy, _vz), (result))); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
} while (0)
|
||||
|
||||
#define testall(x, y, z, result, exceptmask, excepts) do { \
|
||||
@ -124,7 +124,6 @@ test_zeroes(void)
|
||||
static void
|
||||
test_infinities(void)
|
||||
{
|
||||
|
||||
testall(INFINITY, 1.0, -1.0, INFINITY, ALL_STD_EXCEPT, 0);
|
||||
testall(-1.0, INFINITY, 0.0, -INFINITY, ALL_STD_EXCEPT, 0);
|
||||
testall(0.0, 0.0, INFINITY, INFINITY, ALL_STD_EXCEPT, 0);
|
||||
@ -161,7 +160,6 @@ test_infinities(void)
|
||||
static void
|
||||
test_nans(void)
|
||||
{
|
||||
|
||||
testall(NAN, 0.0, 0.0, NAN, ALL_STD_EXCEPT, 0);
|
||||
testall(1.0, NAN, 1.0, NAN, ALL_STD_EXCEPT, 0);
|
||||
testall(1.0, -1.0, NAN, NAN, ALL_STD_EXCEPT, 0);
|
||||
@ -184,7 +182,6 @@ test_nans(void)
|
||||
static void
|
||||
test_small_z(void)
|
||||
{
|
||||
|
||||
/* x*y positive, z positive */
|
||||
if (fegetround() == FE_UPWARD) {
|
||||
test(fmaf, one, one, 0x1.0p-100, 1.0 + FLT_EPSILON,
|
||||
@ -244,7 +241,6 @@ test_small_z(void)
|
||||
static void
|
||||
test_big_z(void)
|
||||
{
|
||||
|
||||
/* z positive, x*y positive */
|
||||
if (fegetround() == FE_UPWARD) {
|
||||
test(fmaf, 0x1.0p-50, 0x1.0p-50, 1.0, 1.0 + FLT_EPSILON,
|
||||
@ -471,74 +467,88 @@ test_double_rounding(void)
|
||||
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
static const int rmodes[] = {
|
||||
FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO
|
||||
};
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(zeroes);
|
||||
ATF_TC_BODY(zeroes, tc)
|
||||
{
|
||||
int rmodes[] = { FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO };
|
||||
unsigned i, j;
|
||||
|
||||
#if defined(__i386__)
|
||||
printf("1..0 # SKIP all testcases fail on i386\n");
|
||||
exit(0);
|
||||
#endif
|
||||
|
||||
j = 1;
|
||||
|
||||
printf("1..19\n");
|
||||
|
||||
for (i = 0; i < nitems(rmodes); i++, j++) {
|
||||
for (size_t i = 0; i < nitems(rmodes); i++) {
|
||||
printf("rmode = %d\n", rmodes[i]);
|
||||
fesetround(rmodes[i]);
|
||||
test_zeroes();
|
||||
printf("ok %d - fma zeroes\n", j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems(rmodes); i++, j++) {
|
||||
ATF_TC_WITHOUT_HEAD(infinities);
|
||||
ATF_TC_BODY(infinities, tc)
|
||||
{
|
||||
#if defined(__amd64__)
|
||||
printf("ok %d # SKIP testcase fails assertion on "
|
||||
"amd64\n", j);
|
||||
continue;
|
||||
#else
|
||||
if (atf_tc_get_config_var_as_bool_wd(tc, "ci", false))
|
||||
atf_tc_expect_fail("https://bugs.freebsd.org/205448");
|
||||
#endif
|
||||
for (size_t i = 0; i < nitems(rmodes); i++) {
|
||||
printf("rmode = %d\n", rmodes[i]);
|
||||
fesetround(rmodes[i]);
|
||||
test_infinities();
|
||||
printf("ok %d - fma infinities\n", j);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(nans);
|
||||
ATF_TC_BODY(nans, tc)
|
||||
{
|
||||
fesetround(FE_TONEAREST);
|
||||
test_nans();
|
||||
printf("ok %d - fma NaNs\n", j);
|
||||
j++;
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems(rmodes); i++, j++) {
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(small_z);
|
||||
ATF_TC_BODY(small_z, tc)
|
||||
{
|
||||
for (size_t i = 0; i < nitems(rmodes); i++) {
|
||||
printf("rmode = %d\n", rmodes[i]);
|
||||
fesetround(rmodes[i]);
|
||||
test_small_z();
|
||||
printf("ok %d - fma small z\n", j);
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < nitems(rmodes); i++, j++) {
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(big_z);
|
||||
ATF_TC_BODY(big_z, tc)
|
||||
{
|
||||
for (size_t i = 0; i < nitems(rmodes); i++) {
|
||||
printf("rmode = %d\n", rmodes[i]);
|
||||
fesetround(rmodes[i]);
|
||||
test_big_z();
|
||||
printf("ok %d - fma big z\n", j);
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(accuracy);
|
||||
ATF_TC_BODY(accuracy, tc)
|
||||
{
|
||||
fesetround(FE_TONEAREST);
|
||||
test_accuracy();
|
||||
printf("ok %d - fma accuracy\n", j);
|
||||
j++;
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(double_rounding);
|
||||
ATF_TC_BODY(double_rounding, tc) {
|
||||
test_double_rounding();
|
||||
printf("ok %d - fma double rounding\n", j);
|
||||
j++;
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, zeroes);
|
||||
ATF_TP_ADD_TC(tp, infinities);
|
||||
ATF_TP_ADD_TC(tp, nans);
|
||||
ATF_TP_ADD_TC(tp, small_z);
|
||||
ATF_TP_ADD_TC(tp, big_z);
|
||||
ATF_TP_ADD_TC(tp, accuracy);
|
||||
ATF_TP_ADD_TC(tp, double_rounding);
|
||||
/*
|
||||
* TODO:
|
||||
* - Tests for subnormals
|
||||
* - Cancellation tests (e.g., z = (double)x*y, but x*y is inexact)
|
||||
*/
|
||||
|
||||
return (0);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -44,57 +44,44 @@ __FBSDID("$FreeBSD$");
|
||||
* Test whether func(x, y) has the expected result, and make sure no
|
||||
* exceptions are raised.
|
||||
*/
|
||||
#define TEST(func, type, x, y, expected) do { \
|
||||
#define TEST(func, type, x, y, expected, rmode) do { \
|
||||
type __x = (x); /* convert before we clear exceptions */ \
|
||||
type __y = (y); \
|
||||
feclearexcept(ALL_STD_EXCEPT); \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(ALL_STD_EXCEPT)); \
|
||||
long double __result = func((__x), (__y)); \
|
||||
if (fetestexcept(ALL_STD_EXCEPT)) { \
|
||||
fprintf(stderr, #func "(%.20Lg, %.20Lg) raised 0x%x\n", \
|
||||
(x), (y), fetestexcept(FE_ALL_EXCEPT)); \
|
||||
ok = 0; \
|
||||
} \
|
||||
if (!fpequal(__result, (expected))) { \
|
||||
fprintf(stderr, #func "(%.20Lg, %.20Lg) = %.20Lg, " \
|
||||
"expected %.20Lg\n", (x), (y), __result, (expected)); \
|
||||
ok = 0; \
|
||||
} \
|
||||
CHECK_FP_EXCEPTIONS_MSG(0, ALL_STD_EXCEPT, \
|
||||
#func "(%.20Lg, %.20Lg) rmode%d", (x), (y), rmode); \
|
||||
ATF_CHECK_MSG(fpequal(__result, (expected)), \
|
||||
#func "(%.20Lg, %.20Lg) rmode%d = %.20Lg, expected %.20Lg\n", \
|
||||
(x), (y), rmode, __result, (expected)); \
|
||||
} while (0)
|
||||
|
||||
static int
|
||||
testall_r(long double big, long double small)
|
||||
static void
|
||||
testall_r(long double big, long double small, int rmode)
|
||||
{
|
||||
int ok;
|
||||
|
||||
long double expected_max = isnan(big) ? small : big;
|
||||
long double expected_min = isnan(small) ? big : small;
|
||||
ok = 1;
|
||||
|
||||
TEST(fmaxf, float, big, small, expected_max);
|
||||
TEST(fmaxf, float, small, big, expected_max);
|
||||
TEST(fmax, double, big, small, expected_max);
|
||||
TEST(fmax, double, small, big, expected_max);
|
||||
TEST(fmaxl, long double, big, small, expected_max);
|
||||
TEST(fmaxl, long double, small, big, expected_max);
|
||||
TEST(fminf, float, big, small, expected_min);
|
||||
TEST(fminf, float, small, big, expected_min);
|
||||
TEST(fmin, double, big, small, expected_min);
|
||||
TEST(fmin, double, small, big, expected_min);
|
||||
TEST(fminl, long double, big, small, expected_min);
|
||||
TEST(fminl, long double, small, big, expected_min);
|
||||
|
||||
return (ok);
|
||||
TEST(fmaxf, float, big, small, expected_max, rmode);
|
||||
TEST(fmaxf, float, small, big, expected_max, rmode);
|
||||
TEST(fmax, double, big, small, expected_max, rmode);
|
||||
TEST(fmax, double, small, big, expected_max, rmode);
|
||||
TEST(fmaxl, long double, big, small, expected_max, rmode);
|
||||
TEST(fmaxl, long double, small, big, expected_max, rmode);
|
||||
TEST(fminf, float, big, small, expected_min, rmode);
|
||||
TEST(fminf, float, small, big, expected_min, rmode);
|
||||
TEST(fmin, double, big, small, expected_min, rmode);
|
||||
TEST(fmin, double, small, big, expected_min, rmode);
|
||||
TEST(fminl, long double, big, small, expected_min, rmode);
|
||||
TEST(fminl, long double, small, big, expected_min, rmode);
|
||||
}
|
||||
|
||||
static const char *comment = NULL;
|
||||
|
||||
/*
|
||||
* Test all the functions: fmaxf, fmax, fmaxl, fminf, fmin, and fminl,
|
||||
* in all rounding modes and with the arguments in different orders.
|
||||
* The input 'big' must be >= 'small'.
|
||||
*/
|
||||
static void
|
||||
testall(int testnum, long double big, long double small)
|
||||
testall(long double big, long double small)
|
||||
{
|
||||
static const int rmodes[] = {
|
||||
FE_TONEAREST, FE_UPWARD, FE_DOWNWARD, FE_TOWARDZERO
|
||||
@ -103,15 +90,8 @@ testall(int testnum, long double big, long double small)
|
||||
|
||||
for (i = 0; i < 4; i++) {
|
||||
fesetround(rmodes[i]);
|
||||
if (!testall_r(big, small)) {
|
||||
fprintf(stderr, "FAILURE in rounding mode %d\n",
|
||||
rmodes[i]);
|
||||
break;
|
||||
}
|
||||
testall_r(big, small, rmodes[i]);
|
||||
}
|
||||
printf("%sok %d - big = %.20Lg, small = %.20Lg%s\n",
|
||||
(i == 4) ? "" : "not ", testnum, big, small,
|
||||
comment == NULL ? "" : comment);
|
||||
}
|
||||
|
||||
/* Clang 3.8.0+ fails the invariants for testcase 6, 7, 10, and 11. */
|
||||
@ -121,34 +101,104 @@ testall(int testnum, long double big, long double small)
|
||||
#define affected_by_bug_208703
|
||||
#endif
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(test1);
|
||||
ATF_TC_BODY(test1, tc)
|
||||
{
|
||||
|
||||
printf("1..12\n");
|
||||
|
||||
testall(1, 1.0, 0.0);
|
||||
testall(2, 42.0, nextafterf(42.0, -INFINITY));
|
||||
testall(3, nextafterf(42.0, INFINITY), 42.0);
|
||||
testall(4, -5.0, -5.0);
|
||||
testall(5, -3.0, -4.0);
|
||||
#ifdef affected_by_bug_208703
|
||||
comment = "# TODO: testcase 6-7 fails invariant with clang 3.8+ (bug 208703)";
|
||||
#endif
|
||||
testall(6, 1.0, NAN);
|
||||
testall(7, INFINITY, NAN);
|
||||
comment = NULL;
|
||||
testall(8, INFINITY, 1.0);
|
||||
testall(9, -3.0, -INFINITY);
|
||||
testall(10, 3.0, -INFINITY);
|
||||
#ifdef affected_by_bug_208703
|
||||
comment = "# TODO: testcase 11-12 fails invariant with clang 3.8+ (bug 208703)";
|
||||
#endif
|
||||
testall(11, NAN, NAN);
|
||||
|
||||
/* This test isn't strictly required to work by C99. */
|
||||
testall(12, 0.0, -0.0);
|
||||
comment = NULL;
|
||||
|
||||
return (0);
|
||||
testall(1.0, 0.0);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test2);
|
||||
ATF_TC_BODY(test2, tc)
|
||||
{
|
||||
testall(42.0, nextafterf(42.0, -INFINITY));
|
||||
}
|
||||
ATF_TC_WITHOUT_HEAD(test3);
|
||||
ATF_TC_BODY(test3, tc)
|
||||
{
|
||||
testall(nextafterf(42.0, INFINITY), 42.0);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test4);
|
||||
ATF_TC_BODY(test4, tc)
|
||||
{
|
||||
testall(-5.0, -5.0);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test5);
|
||||
ATF_TC_BODY(test5, tc)
|
||||
{
|
||||
testall(-3.0, -4.0);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test6);
|
||||
ATF_TC_BODY(test6, tc)
|
||||
{
|
||||
#ifdef affected_by_bug_208703
|
||||
atf_tc_expect_fail("fails invariant with clang 3.8+ (bug 208703)");
|
||||
#endif
|
||||
testall(1.0, NAN);
|
||||
}
|
||||
ATF_TC_WITHOUT_HEAD(test7);
|
||||
ATF_TC_BODY(test7, tc)
|
||||
{
|
||||
#ifdef affected_by_bug_208703
|
||||
atf_tc_expect_fail("fails invariant with clang 3.8+ (bug 208703)");
|
||||
#endif
|
||||
testall(INFINITY, NAN);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test8);
|
||||
ATF_TC_BODY(test8, tc)
|
||||
{
|
||||
testall(INFINITY, 1.0);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test9);
|
||||
ATF_TC_BODY(test9, tc)
|
||||
{
|
||||
testall(-3.0, -INFINITY);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test10);
|
||||
ATF_TC_BODY(test10, tc)
|
||||
{
|
||||
#ifdef affected_by_bug_208703
|
||||
atf_tc_expect_fail("fails invariant with clang 3.8+ (bug 208703)");
|
||||
#endif
|
||||
testall(3.0, -INFINITY);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test11);
|
||||
ATF_TC_BODY(test11, tc)
|
||||
{
|
||||
#ifdef affected_by_bug_208703
|
||||
atf_tc_expect_fail("fails invariant with clang 3.8+ (bug 208703)");
|
||||
#endif
|
||||
testall(NAN, NAN);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(test12);
|
||||
ATF_TC_BODY(test12, tc)
|
||||
{
|
||||
/* This test isn't strictly required to work by C99. */
|
||||
testall(0.0, -0.0);
|
||||
}
|
||||
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, test1);
|
||||
ATF_TP_ADD_TC(tp, test2);
|
||||
ATF_TP_ADD_TC(tp, test3);
|
||||
ATF_TP_ADD_TC(tp, test4);
|
||||
ATF_TP_ADD_TC(tp, test5);
|
||||
ATF_TP_ADD_TC(tp, test6);
|
||||
ATF_TP_ADD_TC(tp, test7);
|
||||
ATF_TP_ADD_TC(tp, test8);
|
||||
ATF_TP_ADD_TC(tp, test9);
|
||||
ATF_TP_ADD_TC(tp, test10);
|
||||
ATF_TP_ADD_TC(tp, test11);
|
||||
ATF_TP_ADD_TC(tp, test12);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -26,58 +26,78 @@
|
||||
* $FreeBSD$
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main(void)
|
||||
#include "test-utils.h"
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(ilogb);
|
||||
ATF_TC_BODY(ilogb, tc)
|
||||
{
|
||||
char buf[128], *end;
|
||||
double d;
|
||||
float f;
|
||||
long double ld;
|
||||
int e, i;
|
||||
|
||||
printf("1..3\n");
|
||||
assert(ilogb(0) == FP_ILOGB0);
|
||||
assert(ilogb(NAN) == FP_ILOGBNAN);
|
||||
assert(ilogb(INFINITY) == INT_MAX);
|
||||
ATF_CHECK_EQ(FP_ILOGB0, ilogb(0));
|
||||
ATF_CHECK_EQ(FP_ILOGBNAN, ilogb(NAN));
|
||||
ATF_CHECK_EQ(INT_MAX, ilogb(INFINITY));
|
||||
for (e = DBL_MIN_EXP - DBL_MANT_DIG; e < DBL_MAX_EXP; e++) {
|
||||
snprintf(buf, sizeof(buf), "0x1.p%d", e);
|
||||
d = strtod(buf, &end);
|
||||
assert(*end == '\0');
|
||||
ATF_CHECK_EQ('\0', *end);
|
||||
i = ilogb(d);
|
||||
assert(i == e);
|
||||
ATF_CHECK_EQ_MSG(e, i, "ilogb(%g) returned %d not %d", d, i, e);
|
||||
}
|
||||
printf("ok 1 - ilogb\n");
|
||||
}
|
||||
|
||||
assert(ilogbf(0) == FP_ILOGB0);
|
||||
assert(ilogbf(NAN) == FP_ILOGBNAN);
|
||||
assert(ilogbf(INFINITY) == INT_MAX);
|
||||
ATF_TC_WITHOUT_HEAD(ilogbf);
|
||||
ATF_TC_BODY(ilogbf, tc)
|
||||
{
|
||||
char buf[128], *end;
|
||||
float f;
|
||||
int e, i;
|
||||
|
||||
ATF_CHECK_EQ(FP_ILOGB0, ilogbf(0));
|
||||
ATF_CHECK_EQ(FP_ILOGBNAN, ilogbf(NAN));
|
||||
ATF_CHECK_EQ(INT_MAX, ilogbf(INFINITY));
|
||||
for (e = FLT_MIN_EXP - FLT_MANT_DIG; e < FLT_MAX_EXP; e++) {
|
||||
snprintf(buf, sizeof(buf), "0x1.p%d", e);
|
||||
f = strtof(buf, &end);
|
||||
assert(*end == '\0');
|
||||
ATF_CHECK_EQ('\0', *end);
|
||||
i = ilogbf(f);
|
||||
assert(i == e);
|
||||
ATF_CHECK_EQ_MSG(e, i, "ilogbf(%g) returned %d not %d", f, i,
|
||||
e);
|
||||
}
|
||||
printf("ok 2 - ilogbf\n");
|
||||
}
|
||||
|
||||
assert(ilogbl(0) == FP_ILOGB0);
|
||||
assert(ilogbl(NAN) == FP_ILOGBNAN);
|
||||
assert(ilogbl(INFINITY) == INT_MAX);
|
||||
ATF_TC_WITHOUT_HEAD(ilogbl);
|
||||
ATF_TC_BODY(ilogbl, tc)
|
||||
{
|
||||
char buf[128], *end;
|
||||
long double ld;
|
||||
int e, i;
|
||||
|
||||
ATF_CHECK_EQ(FP_ILOGB0, ilogbl(0));
|
||||
ATF_CHECK_EQ(FP_ILOGBNAN, ilogbl(NAN));
|
||||
ATF_CHECK_EQ(INT_MAX, ilogbl(INFINITY));
|
||||
for (e = LDBL_MIN_EXP - LDBL_MANT_DIG; e < LDBL_MAX_EXP; e++) {
|
||||
snprintf(buf, sizeof(buf), "0x1.p%d", e);
|
||||
ld = strtold(buf, &end);
|
||||
assert(*end == '\0');
|
||||
ATF_CHECK_EQ('\0', *end);
|
||||
i = ilogbl(ld);
|
||||
assert(i == e);
|
||||
ATF_CHECK_EQ_MSG(e, i, "ilogbl(%Lg) returned %d not %d", ld, i,
|
||||
e);
|
||||
}
|
||||
printf("ok 3 - ilogbl\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, ilogb);
|
||||
ATF_TP_ADD_TC(tp, ilogbf);
|
||||
ATF_TP_ADD_TC(tp, ilogbl);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <complex.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
@ -61,9 +60,10 @@ __FBSDID("$FreeBSD$");
|
||||
volatile long double complex _d = z; \
|
||||
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
|
||||
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(cfpequal_cs((func)(_d), (result), (checksign))); \
|
||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
ATF_CHECK(cfpequal_cs((func)(_d), (result), (checksign))); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
|
||||
#func, #z); \
|
||||
} while (0)
|
||||
|
||||
/*
|
||||
@ -74,7 +74,7 @@ __FBSDID("$FreeBSD$");
|
||||
volatile long double complex _d = z; \
|
||||
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
|
||||
creall(_d), cimagl(_d), creall(result), cimagl(result)); \
|
||||
assert(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
|
||||
ATF_CHECK(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
|
||||
} while (0)
|
||||
|
||||
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */
|
||||
@ -124,8 +124,8 @@ c3pi = 9.42477796076937971538793014983850839L;
|
||||
|
||||
|
||||
/* Tests for 0 */
|
||||
static void
|
||||
test_zero(void)
|
||||
ATF_TC_WITHOUT_HEAD(zero);
|
||||
ATF_TC_BODY(zero, tc)
|
||||
{
|
||||
long double complex zero = CMPLXL(0.0, 0.0);
|
||||
|
||||
@ -144,8 +144,8 @@ test_zero(void)
|
||||
/*
|
||||
* Tests for NaN inputs.
|
||||
*/
|
||||
static void
|
||||
test_nan(void)
|
||||
ATF_TC_WITHOUT_HEAD(nan);
|
||||
ATF_TC_BODY(nan, tc)
|
||||
{
|
||||
long double complex nan_nan = CMPLXL(NAN, NAN);
|
||||
long double complex z;
|
||||
@ -223,8 +223,8 @@ test_nan(void)
|
||||
testall(catan, z, CMPLXL(NAN, 0.0), ALL_STD_EXCEPT, 0, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
test_inf(void)
|
||||
ATF_TC_WITHOUT_HEAD(inf);
|
||||
ATF_TC_BODY(inf, tc)
|
||||
{
|
||||
long double complex z;
|
||||
|
||||
@ -270,8 +270,8 @@ test_inf(void)
|
||||
}
|
||||
|
||||
/* Tests along the real and imaginary axes. */
|
||||
static void
|
||||
test_axes(void)
|
||||
ATF_TC_WITHOUT_HEAD(axes);
|
||||
ATF_TC_BODY(axes, tc)
|
||||
{
|
||||
static const long double nums[] = {
|
||||
-2, -1, -0.5, 0.5, 1, 2
|
||||
@ -307,8 +307,8 @@ test_axes(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_small(void)
|
||||
ATF_TC_WITHOUT_HEAD(small);
|
||||
ATF_TC_BODY(small, tc)
|
||||
{
|
||||
/*
|
||||
* z = 0.75 + i 0.25
|
||||
@ -333,36 +333,20 @@ test_small(void)
|
||||
}
|
||||
|
||||
/* Test inputs that might cause overflow in a sloppy implementation. */
|
||||
static void
|
||||
test_large(void)
|
||||
ATF_TC_WITHOUT_HEAD(large);
|
||||
ATF_TC_BODY(large, tc)
|
||||
{
|
||||
|
||||
/* TODO: Write these tests */
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, zero);
|
||||
ATF_TP_ADD_TC(tp, nan);
|
||||
ATF_TP_ADD_TC(tp, inf);
|
||||
ATF_TP_ADD_TC(tp, axes);
|
||||
ATF_TP_ADD_TC(tp, small);
|
||||
ATF_TP_ADD_TC(tp, large);
|
||||
|
||||
printf("1..6\n");
|
||||
|
||||
test_zero();
|
||||
printf("ok 1 - invctrig zero\n");
|
||||
|
||||
test_nan();
|
||||
printf("ok 2 - invctrig nan\n");
|
||||
|
||||
test_inf();
|
||||
printf("ok 3 - invctrig inf\n");
|
||||
|
||||
test_axes();
|
||||
printf("ok 4 - invctrig axes\n");
|
||||
|
||||
test_small();
|
||||
printf("ok 5 - invctrig small\n");
|
||||
|
||||
test_large();
|
||||
printf("ok 6 - invctrig large\n");
|
||||
|
||||
return (0);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -54,9 +53,10 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#define test_tol(func, x, result, tol, excepts) do { \
|
||||
volatile long double _in = (x), _out = (result); \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(fpequal_tol(func(_in), _out, (tol), CS_BOTH)); \
|
||||
assert(((void)func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
ATF_CHECK(fpequal_tol(func(_in), _out, (tol), CS_BOTH)); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, ALL_STD_EXCEPT, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
} while (0)
|
||||
#define test(func, x, result, excepts) \
|
||||
test_tol(func, (x), (result), 0, (excepts))
|
||||
@ -83,9 +83,10 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#define test2_tol(func, y, x, result, tol, excepts) do { \
|
||||
volatile long double _iny = (y), _inx = (x), _out = (result); \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(fpequal_tol(func(_iny, _inx), _out, (tol), CS_BOTH)); \
|
||||
assert(((void)func, fetestexcept(ALL_STD_EXCEPT) == (excepts))); \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
ATF_CHECK(fpequal_tol(func(_iny, _inx), _out, (tol), CS_BOTH)); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, ALL_STD_EXCEPT, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
} while (0)
|
||||
#define test2(func, y, x, result, excepts) \
|
||||
test2_tol(func, (y), (x), (result), 0, (excepts))
|
||||
@ -123,8 +124,8 @@ sqrt2m1 = 4.14213562373095048801688724209698081e-01L;
|
||||
* Test special case inputs in asin(), acos() and atan(): signed
|
||||
* zeroes, infinities, and NaNs.
|
||||
*/
|
||||
static void
|
||||
test_special(void)
|
||||
ATF_TC_WITHOUT_HEAD(special);
|
||||
ATF_TC_BODY(special, tc)
|
||||
{
|
||||
|
||||
testall(asin, 0.0, 0.0, 0);
|
||||
@ -150,8 +151,8 @@ test_special(void)
|
||||
* Test special case inputs in atan2(), where the exact value of y/x is
|
||||
* zero or non-finite.
|
||||
*/
|
||||
static void
|
||||
test_special_atan2(void)
|
||||
ATF_TC_WITHOUT_HEAD(special_atan2);
|
||||
ATF_TC_BODY(special_atan2, tc)
|
||||
{
|
||||
long double z;
|
||||
int e;
|
||||
@ -236,8 +237,8 @@ test_special_atan2(void)
|
||||
* Test various inputs to asin(), acos() and atan() and verify that the
|
||||
* results are accurate to within 1 ulp.
|
||||
*/
|
||||
static void
|
||||
test_accuracy(void)
|
||||
ATF_TC_WITHOUT_HEAD(accuracy);
|
||||
ATF_TC_BODY(accuracy, tc)
|
||||
{
|
||||
|
||||
/* We expect correctly rounded results for these basic cases. */
|
||||
@ -274,8 +275,8 @@ test_accuracy(void)
|
||||
* Test inputs to atan2() where x is a power of 2. These are easy cases
|
||||
* because y/x is exact.
|
||||
*/
|
||||
static void
|
||||
test_p2x_atan2(void)
|
||||
ATF_TC_WITHOUT_HEAD(p2x_atan2);
|
||||
ATF_TC_BODY(p2x_atan2, tc)
|
||||
{
|
||||
|
||||
testall2(atan2, 1.0, 1.0, pi / 4, FE_INEXACT);
|
||||
@ -297,8 +298,8 @@ test_p2x_atan2(void)
|
||||
/*
|
||||
* Test inputs very close to 0.
|
||||
*/
|
||||
static void
|
||||
test_tiny(void)
|
||||
ATF_TC_WITHOUT_HEAD(tiny);
|
||||
ATF_TC_BODY(tiny, tc)
|
||||
{
|
||||
float tiny = 0x1.23456p-120f;
|
||||
|
||||
@ -332,8 +333,8 @@ test_tiny(void)
|
||||
/*
|
||||
* Test very large inputs to atan().
|
||||
*/
|
||||
static void
|
||||
test_atan_huge(void)
|
||||
ATF_TC_WITHOUT_HEAD(atan_huge);
|
||||
ATF_TC_BODY(atan_huge, tc)
|
||||
{
|
||||
float huge = 0x1.23456p120;
|
||||
|
||||
@ -428,8 +429,8 @@ tanatanl(long double x)
|
||||
return (tanl(atanl(x)));
|
||||
}
|
||||
|
||||
static void
|
||||
test_inverse(void)
|
||||
ATF_TC_WITHOUT_HEAD(inverse);
|
||||
ATF_TC_BODY(inverse, tc)
|
||||
{
|
||||
float i;
|
||||
|
||||
@ -442,37 +443,15 @@ test_inverse(void)
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, special);
|
||||
ATF_TP_ADD_TC(tp, special_atan2);
|
||||
ATF_TP_ADD_TC(tp, accuracy);
|
||||
ATF_TP_ADD_TC(tp, p2x_atan2);
|
||||
ATF_TP_ADD_TC(tp, tiny);
|
||||
ATF_TP_ADD_TC(tp, atan_huge);
|
||||
ATF_TP_ADD_TC(tp, inverse);
|
||||
|
||||
#if defined(__i386__)
|
||||
printf("1..0 # SKIP fails all assertions on i386\n");
|
||||
return (0);
|
||||
#endif
|
||||
|
||||
printf("1..7\n");
|
||||
|
||||
test_special();
|
||||
printf("ok 1 - special\n");
|
||||
|
||||
test_special_atan2();
|
||||
printf("ok 2 - atan2 special\n");
|
||||
|
||||
test_accuracy();
|
||||
printf("ok 3 - accuracy\n");
|
||||
|
||||
test_p2x_atan2();
|
||||
printf("ok 4 - atan2 p2x\n");
|
||||
|
||||
test_tiny();
|
||||
printf("ok 5 - tiny inputs\n");
|
||||
|
||||
test_atan_huge();
|
||||
printf("ok 6 - atan huge inputs\n");
|
||||
|
||||
test_inverse();
|
||||
printf("ok 7 - inverse\n");
|
||||
|
||||
return (0);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -32,7 +32,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
@ -59,24 +58,18 @@ __FBSDID("$FreeBSD$");
|
||||
* XXX The volatile here is to avoid gcc's bogus constant folding and work
|
||||
* around the lack of support for the FENV_ACCESS pragma.
|
||||
*/
|
||||
#define test(func, x, result, exceptmask, excepts) do { \
|
||||
volatile long double _d = x; \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(fpequal((func)(_d), (result))); \
|
||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
} while (0)
|
||||
|
||||
#define test(func, x, result, exceptmask, excepts) do { \
|
||||
volatile long double _d = x; \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert(fpequal((func)(_d), (result))); \
|
||||
assert(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
#define test(func, x, result, exceptmask, excepts) do { \
|
||||
volatile long double _d = x; \
|
||||
ATF_CHECK_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
ATF_CHECK(fpequal((func)(_d), (result))); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
} while (0)
|
||||
|
||||
#define test_tol(func, z, result, tol) do { \
|
||||
volatile long double _d = z; \
|
||||
debug(" testing %6s(%15La) ~= % .36Le\n", #func, _d, result); \
|
||||
assert(fpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
|
||||
ATF_CHECK(fpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \
|
||||
} while (0)
|
||||
|
||||
/* Test all the functions that compute log(x). */
|
||||
@ -99,8 +92,8 @@ __FBSDID("$FreeBSD$");
|
||||
test(log1pl, x, result, exceptmask, excepts); \
|
||||
} while (0)
|
||||
|
||||
static void
|
||||
run_generic_tests(void)
|
||||
ATF_TC_WITHOUT_HEAD(generic_tests);
|
||||
ATF_TC_BODY(generic_tests, tc)
|
||||
{
|
||||
|
||||
/* log(1) == 0, no exceptions raised */
|
||||
@ -128,8 +121,8 @@ run_generic_tests(void)
|
||||
testall1(-1.0, -INFINITY, ALL_STD_EXCEPT & ~FE_INEXACT, FE_DIVBYZERO);
|
||||
}
|
||||
|
||||
static void
|
||||
run_log2_tests(void)
|
||||
ATF_TC_WITHOUT_HEAD(log2_tests);
|
||||
ATF_TC_BODY(log2_tests, tc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
@ -137,26 +130,23 @@ run_log2_tests(void)
|
||||
* We should insist that log2() return exactly the correct
|
||||
* result and not raise an inexact exception for powers of 2.
|
||||
*/
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0);
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
|
||||
for (i = FLT_MIN_EXP - FLT_MANT_DIG; i < FLT_MAX_EXP; i++) {
|
||||
assert(log2f(ldexpf(1.0, i)) == i);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(i, log2f(ldexpf(1.0, i)));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
for (i = DBL_MIN_EXP - DBL_MANT_DIG; i < DBL_MAX_EXP; i++) {
|
||||
assert(log2(ldexp(1.0, i)) == i);
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK_EQ(i, log2(ldexp(1.0, i)));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
for (i = LDBL_MIN_EXP - LDBL_MANT_DIG; i < LDBL_MAX_EXP; i++) {
|
||||
assert(log2l(ldexpl(1.0, i)) == i);
|
||||
#if 0
|
||||
/* XXX This test does not pass yet. */
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
#endif
|
||||
ATF_CHECK_EQ(i, log2l(ldexpl(1.0, i)));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_roundingmode_tests(void)
|
||||
ATF_TC_WITHOUT_HEAD(roundingmode_tests);
|
||||
ATF_TC_BODY(roundingmode_tests, tc)
|
||||
{
|
||||
|
||||
/*
|
||||
@ -189,8 +179,8 @@ run_roundingmode_tests(void)
|
||||
fesetround(FE_TONEAREST);
|
||||
}
|
||||
|
||||
static void
|
||||
run_accuracy_tests(void)
|
||||
ATF_TC_WITHOUT_HEAD(accuracy_tests);
|
||||
ATF_TC_BODY(accuracy_tests, tc)
|
||||
{
|
||||
static const struct {
|
||||
float x;
|
||||
@ -243,10 +233,9 @@ run_accuracy_tests(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
run_log1p_accuracy_tests(void)
|
||||
ATF_TC_WITHOUT_HEAD(log1p_accuracy_tests);
|
||||
ATF_TC_BODY(log1p_accuracy_tests, tc)
|
||||
{
|
||||
|
||||
test_tol(log1pf, 0x0.333333p0F,
|
||||
1.82321546859847114303367992804596800640e-1L, FLT_ULP());
|
||||
test_tol(log1p, 0x0.3333333333333p0,
|
||||
@ -262,26 +251,14 @@ run_log1p_accuracy_tests(void)
|
||||
-2.23143551314209755752742563153765697950e-1L, LDBL_ULP());
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
|
||||
printf("1..5\n");
|
||||
ATF_TP_ADD_TC(tp, generic_tests);
|
||||
ATF_TP_ADD_TC(tp, log2_tests);
|
||||
ATF_TP_ADD_TC(tp, roundingmode_tests);
|
||||
ATF_TP_ADD_TC(tp, accuracy_tests);
|
||||
ATF_TP_ADD_TC(tp, log1p_accuracy_tests);
|
||||
|
||||
run_generic_tests();
|
||||
printf("ok 1 - logarithm\n");
|
||||
|
||||
run_log2_tests();
|
||||
printf("ok 2 - logarithm\n");
|
||||
|
||||
run_roundingmode_tests();
|
||||
printf("ok 3 - logarithm\n");
|
||||
|
||||
run_accuracy_tests();
|
||||
printf("ok 4 - logarithm\n");
|
||||
|
||||
run_log1p_accuracy_tests();
|
||||
printf("ok 5 - logarithm\n");
|
||||
|
||||
return (0);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
@ -49,10 +48,10 @@ __FBSDID("$FreeBSD$");
|
||||
*/
|
||||
#define test(func, x, result, excepts) do { \
|
||||
volatile double _d = x; \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert((func)(_d) == (result) || fetestexcept(FE_INVALID)); \
|
||||
assert((fetestexcept(FE_ALL_EXCEPT) & ALL_STD_EXCEPT) \
|
||||
== (excepts)); \
|
||||
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
ATF_CHECK((func)(_d) == (result) || fetestexcept(FE_INVALID)); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, FE_ALL_EXCEPT & ALL_STD_EXCEPT,\
|
||||
"for %s(%s)", #func, #x); \
|
||||
} while (0)
|
||||
|
||||
#define testall(x, result, excepts) do { \
|
||||
@ -71,12 +70,11 @@ __FBSDID("$FreeBSD$");
|
||||
static void
|
||||
run_tests(void)
|
||||
{
|
||||
|
||||
assert(fesetround(FE_DOWNWARD) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_DOWNWARD));
|
||||
testall(0.75, 0, FE_INEXACT);
|
||||
testall(-0.5, -1, FE_INEXACT);
|
||||
|
||||
assert(fesetround(FE_TONEAREST) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_TONEAREST));
|
||||
testall(0.0, 0, 0);
|
||||
testall(0.25, 0, FE_INEXACT);
|
||||
testall(0.5, 0, FE_INEXACT);
|
||||
@ -88,65 +86,64 @@ run_tests(void)
|
||||
testall(NAN, IGNORE, FE_INVALID);
|
||||
|
||||
#if (LONG_MAX == 0x7fffffffl)
|
||||
assert(fesetround(FE_UPWARD) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_UPWARD));
|
||||
test(lrint, 0x7fffffff.8p0, IGNORE, FE_INVALID);
|
||||
test(lrint, -0x80000000.4p0, -0x80000000l, FE_INEXACT);
|
||||
test(lrint, -0x80000000.4p0, (long)-0x80000000l, FE_INEXACT);
|
||||
|
||||
assert(fesetround(FE_DOWNWARD) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_DOWNWARD));
|
||||
test(lrint, -0x80000000.8p0, IGNORE, FE_INVALID);
|
||||
test(lrint, 0x80000000.0p0, IGNORE, FE_INVALID);
|
||||
test(lrint, 0x7fffffff.4p0, 0x7fffffffl, FE_INEXACT);
|
||||
test(lrintf, 0x80000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(lrintf, 0x7fffff80.0p0f, 0x7fffff80l, 0);
|
||||
|
||||
assert(fesetround(FE_TOWARDZERO) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_TOWARDZERO));
|
||||
test(lrint, 0x7fffffff.8p0, 0x7fffffffl, FE_INEXACT);
|
||||
test(lrint, -0x80000000.8p0, -0x80000000l, FE_INEXACT);
|
||||
test(lrint, 0x80000000.0p0, IGNORE, FE_INVALID);
|
||||
test(lrintf, 0x80000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(lrintf, 0x7fffff80.0p0f, 0x7fffff80l, 0);
|
||||
#elif (LONG_MAX == 0x7fffffffffffffffll)
|
||||
assert(fesetround(FE_TONEAREST) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_TONEAREST));
|
||||
test(lrint, 0x8000000000000000.0p0, IGNORE, FE_INVALID);
|
||||
test(lrintf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(lrint, 0x7ffffffffffffc00.0p0, 0x7ffffffffffffc00l, 0);
|
||||
test(lrintf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000l, 0);
|
||||
test(lrint, -0x8000000000000800.0p0, IGNORE, FE_INVALID);
|
||||
test(lrintf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(lrint, -0x8000000000000000.0p0, -0x8000000000000000l, 0);
|
||||
test(lrintf, -0x8000000000000000.0p0f, -0x8000000000000000l, 0);
|
||||
test(lrint, -0x8000000000000000.0p0, (long long)-0x8000000000000000ul, 0);
|
||||
test(lrintf, -0x8000000000000000.0p0f, (long long)-0x8000000000000000ul, 0);
|
||||
#else
|
||||
#error "Unsupported long size"
|
||||
#endif
|
||||
|
||||
#if (LLONG_MAX == 0x7fffffffffffffffLL)
|
||||
assert(fesetround(FE_TONEAREST) == 0);
|
||||
ATF_REQUIRE_EQ(0, fesetround(FE_TONEAREST));
|
||||
test(llrint, 0x8000000000000000.0p0, IGNORE, FE_INVALID);
|
||||
test(llrintf, 0x8000000000000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(llrint, 0x7ffffffffffffc00.0p0, 0x7ffffffffffffc00ll, 0);
|
||||
test(llrintf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000ll, 0);
|
||||
test(llrint, -0x8000000000000800.0p0, IGNORE, FE_INVALID);
|
||||
test(llrintf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(llrint, -0x8000000000000000.0p0, -0x8000000000000000ll, 0);
|
||||
test(llrintf, -0x8000000000000000.0p0f, -0x8000000000000000ll, 0);
|
||||
test(llrint, -0x8000000000000000.0p0, (long long)-0x8000000000000000ull, 0);
|
||||
test(llrintf, -0x8000000000000000.0p0f, (long long)-0x8000000000000000ull, 0);
|
||||
#else
|
||||
#error "Unsupported long long size"
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(lrint);
|
||||
ATF_TC_BODY(lrint, tc)
|
||||
{
|
||||
|
||||
printf("1..1\n");
|
||||
|
||||
run_tests();
|
||||
#ifdef __i386__
|
||||
fpsetprec(FP_PE);
|
||||
run_tests();
|
||||
#endif
|
||||
|
||||
printf("ok 1 - lrint\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, lrint);
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -31,21 +31,33 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
#define IGNORE 0x12345
|
||||
|
||||
/*
|
||||
* XXX The volatile here is to avoid gcc's bogus constant folding and work
|
||||
* around the lack of support for the FENV_ACCESS pragma.
|
||||
*/
|
||||
#define test(func, x, result, excepts) do { \
|
||||
volatile double _d = x; \
|
||||
assert(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
assert((func)(_d) == (result) || fetestexcept(FE_INVALID)); \
|
||||
assert(fetestexcept(FE_ALL_EXCEPT) == (excepts)); \
|
||||
#define test(func, x, result, excepts) do { \
|
||||
volatile double _d = x; \
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
|
||||
volatile double _r = (func)(_d); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, FE_ALL_EXCEPT, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
if ((excepts & FE_INVALID) != 0) { \
|
||||
ATF_REQUIRE_EQ(result, IGNORE); \
|
||||
ATF_CHECK_EQ_MSG(FE_INVALID, fetestexcept(FE_INVALID), \
|
||||
"FE_INVALID not set correctly for %s(%s)", #func, #x); \
|
||||
} else { \
|
||||
ATF_REQUIRE_MSG(result != IGNORE, "Expected can't be IGNORE!"); \
|
||||
ATF_REQUIRE_EQ(result, (__STRING(func(_d)), _r)); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define testall(x, result, excepts) do { \
|
||||
@ -55,16 +67,12 @@ __FBSDID("$FreeBSD$");
|
||||
test(llroundf, x, result, excepts); \
|
||||
} while (0)
|
||||
|
||||
#define IGNORE 0
|
||||
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
ATF_TC_WITHOUT_HEAD(main);
|
||||
ATF_TC_BODY(main, tc)
|
||||
{
|
||||
|
||||
printf("1..1\n");
|
||||
|
||||
atf_tc_expect_fail("https://bugs.freebsd.org/205451");
|
||||
testall(0.0, 0, 0);
|
||||
testall(0.25, 0, FE_INEXACT);
|
||||
testall(0.5, 1, FE_INEXACT);
|
||||
@ -90,8 +98,8 @@ main(int argc, char *argv[])
|
||||
test(lroundf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000l, 0);
|
||||
test(lround, -0x8000000000000800.0p0, IGNORE, FE_INVALID);
|
||||
test(lroundf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(lround, -0x8000000000000000.0p0, -0x8000000000000000l, 0);
|
||||
test(lroundf, -0x8000000000000000.0p0f, -0x8000000000000000l, 0);
|
||||
test(lround, -0x8000000000000000.0p0, (long)-0x8000000000000000l, 0);
|
||||
test(lroundf, -0x8000000000000000.0p0f, (long)-0x8000000000000000l, 0);
|
||||
#else
|
||||
#error "Unsupported long size"
|
||||
#endif
|
||||
@ -103,13 +111,16 @@ main(int argc, char *argv[])
|
||||
test(llroundf, 0x7fffff8000000000.0p0f, 0x7fffff8000000000ll, 0);
|
||||
test(llround, -0x8000000000000800.0p0, IGNORE, FE_INVALID);
|
||||
test(llroundf, -0x8000010000000000.0p0f, IGNORE, FE_INVALID);
|
||||
test(llround, -0x8000000000000000.0p0, -0x8000000000000000ll, 0);
|
||||
test(llroundf, -0x8000000000000000.0p0f, -0x8000000000000000ll, 0);
|
||||
test(llround, -0x8000000000000000.0p0, (long long)-0x8000000000000000ll, 0);
|
||||
test(llroundf, -0x8000000000000000.0p0f, (long long)-0x8000000000000000ll, 0);
|
||||
#else
|
||||
#error "Unsupported long long size"
|
||||
#endif
|
||||
|
||||
printf("ok 1 - lround\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, main);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -1,10 +0,0 @@
|
||||
#!/bin/sh
|
||||
# $FreeBSD$
|
||||
|
||||
cd `dirname $0`
|
||||
|
||||
executable=`basename $0 .t`
|
||||
|
||||
make $executable 2>&1 > /dev/null
|
||||
|
||||
exec ./$executable
|
@ -33,7 +33,6 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <locale.h>
|
||||
@ -42,6 +41,8 @@ __FBSDID("$FreeBSD$");
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
static void
|
||||
testnan(const char *nan_format)
|
||||
{
|
||||
@ -65,58 +66,58 @@ testnan(const char *nan_format)
|
||||
}
|
||||
|
||||
af[0] = nanf(nan_format);
|
||||
assert(isnan(af[0]));
|
||||
ATF_REQUIRE(isnan(af[0]));
|
||||
af[1] = strtof(nan_str, &end);
|
||||
assert(end == nan_str + strlen(nan_str));
|
||||
assert(sscanf(nan_str, "%e", &af[2]) == 1);
|
||||
assert(memcmp(&af[0], &af[1], sizeof(float)) == 0);
|
||||
assert(memcmp(&af[1], &af[2], sizeof(float)) == 0);
|
||||
ATF_REQUIRE(end == nan_str + strlen(nan_str));
|
||||
ATF_REQUIRE(sscanf(nan_str, "%e", &af[2]) == 1);
|
||||
ATF_REQUIRE(memcmp(&af[0], &af[1], sizeof(float)) == 0);
|
||||
ATF_REQUIRE(memcmp(&af[1], &af[2], sizeof(float)) == 0);
|
||||
if (*nan_format == '\0') {
|
||||
/* nanf("") == strtof("nan") */
|
||||
af[3] = strtof("nan", NULL);
|
||||
assert(memcmp(&af[2], &af[3], sizeof(float)) == 0);
|
||||
ATF_REQUIRE(memcmp(&af[2], &af[3], sizeof(float)) == 0);
|
||||
}
|
||||
|
||||
ad[0] = nan(nan_format);
|
||||
assert(isnan(ad[0]));
|
||||
ATF_REQUIRE(isnan(ad[0]));
|
||||
ad[1] = strtod(nan_str, &end);
|
||||
assert(end == nan_str + strlen(nan_str));
|
||||
assert(sscanf(nan_str, "%le", &ad[2]) == 1);
|
||||
assert(memcmp(&ad[0], &ad[1], sizeof(double)) == 0);
|
||||
assert(memcmp(&ad[1], &ad[2], sizeof(double)) == 0);
|
||||
ATF_REQUIRE(end == nan_str + strlen(nan_str));
|
||||
ATF_REQUIRE(sscanf(nan_str, "%le", &ad[2]) == 1);
|
||||
ATF_REQUIRE(memcmp(&ad[0], &ad[1], sizeof(double)) == 0);
|
||||
ATF_REQUIRE(memcmp(&ad[1], &ad[2], sizeof(double)) == 0);
|
||||
if (*nan_format == '\0') {
|
||||
/* nan("") == strtod("nan") */
|
||||
ad[3] = strtod("nan", NULL);
|
||||
assert(memcmp(&ad[2], &ad[3], sizeof(double)) == 0);
|
||||
ATF_REQUIRE(memcmp(&ad[2], &ad[3], sizeof(double)) == 0);
|
||||
}
|
||||
|
||||
ald[0] = nanl(nan_format);
|
||||
assert(isnan(ald[0]));
|
||||
ATF_REQUIRE(isnan(ald[0]));
|
||||
ald[1] = strtold(nan_str, &end);
|
||||
assert(end == nan_str + strlen(nan_str));
|
||||
assert(sscanf(nan_str, "%Le", &ald[2]) == 1);
|
||||
assert(memcmp(&ald[0], &ald[1], sizeof(long double)) == 0);
|
||||
assert(memcmp(&ald[1], &ald[2], sizeof(long double)) == 0);
|
||||
ATF_REQUIRE(end == nan_str + strlen(nan_str));
|
||||
ATF_REQUIRE(sscanf(nan_str, "%Le", &ald[2]) == 1);
|
||||
ATF_REQUIRE(memcmp(&ald[0], &ald[1], sizeof(long double)) == 0);
|
||||
ATF_REQUIRE(memcmp(&ald[1], &ald[2], sizeof(long double)) == 0);
|
||||
if (*nan_format == '\0') {
|
||||
/* nanl("") == strtold("nan") */
|
||||
ald[3] = strtold("nan", NULL);
|
||||
assert(memcmp(&ald[2], &ald[3], sizeof(long double)) == 0);
|
||||
ATF_REQUIRE(memcmp(&ald[2], &ald[3], sizeof(long double)) == 0);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(nan);
|
||||
ATF_TC_BODY(nan, tc)
|
||||
{
|
||||
|
||||
printf("1..1\n");
|
||||
|
||||
/* Die if a signalling NaN is returned */
|
||||
feenableexcept(FE_INVALID);
|
||||
|
||||
testnan("0x1234");
|
||||
testnan("");
|
||||
|
||||
printf("ok 1 - nan\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, nan);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -36,15 +36,12 @@
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
static int testnum;
|
||||
|
||||
static const int rmodes[] = {
|
||||
FE_TONEAREST, FE_DOWNWARD, FE_UPWARD, FE_TOWARDZERO,
|
||||
};
|
||||
@ -95,25 +92,23 @@ test_nearby(int testindex)
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sizeof(rmodes) / sizeof(rmodes[0]); i++) {
|
||||
fesetround(rmodes[i]);
|
||||
feclearexcept(ALL_STD_EXCEPT);
|
||||
ATF_REQUIRE_EQ(0, fesetround(rmodes[i]));
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(ALL_STD_EXCEPT));
|
||||
|
||||
in = tests[testindex].in;
|
||||
out = get_output(testindex, i, 0);
|
||||
assert(fpequal(out, libnearbyintf(in)));
|
||||
assert(fpequal(out, nearbyint(in)));
|
||||
assert(fpequal(out, nearbyintl(in)));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK(fpequal(out, libnearbyintf(in)));
|
||||
ATF_CHECK(fpequal(out, nearbyint(in)));
|
||||
ATF_CHECK(fpequal(out, nearbyintl(in)));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
|
||||
in = -tests[testindex].in;
|
||||
out = get_output(testindex, i, 1);
|
||||
assert(fpequal(out, nearbyintf(in)));
|
||||
assert(fpequal(out, nearbyint(in)));
|
||||
assert(fpequal(out, nearbyintl(in)));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK(fpequal(out, nearbyintf(in)));
|
||||
ATF_CHECK(fpequal(out, nearbyint(in)));
|
||||
ATF_CHECK(fpequal(out, nearbyintl(in)));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
|
||||
printf("ok %d\t\t# nearbyint(+%g)\n", testnum++, in);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -126,8 +121,8 @@ test_modf(int testindex)
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < sizeof(rmodes) / sizeof(rmodes[0]); i++) {
|
||||
fesetround(rmodes[i]);
|
||||
feclearexcept(ALL_STD_EXCEPT);
|
||||
ATF_REQUIRE_EQ(0, fesetround(rmodes[i]));
|
||||
ATF_REQUIRE_EQ(0, feclearexcept(ALL_STD_EXCEPT));
|
||||
|
||||
in = tests[testindex].in;
|
||||
ipart_expected = tests[testindex].out[1];
|
||||
@ -135,41 +130,42 @@ test_modf(int testindex)
|
||||
isinf(ipart_expected) ? 0.0 : in - ipart_expected, in);
|
||||
ipartl = ipart = ipartf = 42.0;
|
||||
|
||||
assert(fpequal(out, modff(in, &ipartf)));
|
||||
assert(fpequal(ipart_expected, ipartf));
|
||||
assert(fpequal(out, modf(in, &ipart)));
|
||||
assert(fpequal(ipart_expected, ipart));
|
||||
assert(fpequal(out, modfl(in, &ipartl)));
|
||||
assert(fpequal(ipart_expected, ipartl));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK(fpequal(out, modff(in, &ipartf)));
|
||||
ATF_CHECK(fpequal(ipart_expected, ipartf));
|
||||
ATF_CHECK(fpequal(out, modf(in, &ipart)));
|
||||
ATF_CHECK(fpequal(ipart_expected, ipart));
|
||||
ATF_CHECK(fpequal(out, modfl(in, &ipartl)));
|
||||
ATF_CHECK(fpequal(ipart_expected, ipartl));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
|
||||
in = -in;
|
||||
ipart_expected = -ipart_expected;
|
||||
out = -out;
|
||||
ipartl = ipart = ipartf = 42.0;
|
||||
assert(fpequal(out, modff(in, &ipartf)));
|
||||
assert(fpequal(ipart_expected, ipartf));
|
||||
assert(fpequal(out, modf(in, &ipart)));
|
||||
assert(fpequal(ipart_expected, ipart));
|
||||
assert(fpequal(out, modfl(in, &ipartl)));
|
||||
assert(fpequal(ipart_expected, ipartl));
|
||||
assert(fetestexcept(ALL_STD_EXCEPT) == 0);
|
||||
ATF_CHECK(fpequal(out, modff(in, &ipartf)));
|
||||
ATF_CHECK(fpequal(ipart_expected, ipartf));
|
||||
ATF_CHECK(fpequal(out, modf(in, &ipart)));
|
||||
ATF_CHECK(fpequal(ipart_expected, ipart));
|
||||
ATF_CHECK(fpequal(out, modfl(in, &ipartl)));
|
||||
ATF_CHECK(fpequal(ipart_expected, ipartl));
|
||||
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
|
||||
}
|
||||
|
||||
printf("ok %d\t\t# modf(+%g)\n", testnum++, in);
|
||||
}
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(nearbyint);
|
||||
ATF_TC_BODY(nearbyint, tc)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
printf("1..%zu\n", (size_t)(nitems(tests) * 2));
|
||||
testnum = 1;
|
||||
for (i = 0; i < nitems(tests); i++) {
|
||||
test_nearby(i);
|
||||
test_modf(i);
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, nearbyint);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -72,14 +72,16 @@ static void _testl(const char *, int, long double, long double, int);
|
||||
static double idd(double);
|
||||
static float idf(float);
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
static const int ex_under = FE_UNDERFLOW | FE_INEXACT; /* shorthand */
|
||||
static const int ex_over = FE_OVERFLOW | FE_INEXACT;
|
||||
long double ldbl_small, ldbl_eps, ldbl_max;
|
||||
static const int ex_under = FE_UNDERFLOW | FE_INEXACT; /* shorthand */
|
||||
static const int ex_over = FE_OVERFLOW | FE_INEXACT;
|
||||
static const long double ldbl_eps = LDBL_EPSILON;
|
||||
|
||||
printf("1..5\n");
|
||||
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(zeros);
|
||||
ATF_TC_BODY(zeros, tc)
|
||||
{
|
||||
long double ldbl_small;
|
||||
|
||||
#ifdef __i386__
|
||||
fpsetprec(FP_PE);
|
||||
@ -90,8 +92,6 @@ main(void)
|
||||
* double format.
|
||||
*/
|
||||
ldbl_small = ldexpl(1.0, LDBL_MIN_EXP - LDBL_MANT_DIG);
|
||||
ldbl_eps = LDBL_EPSILON;
|
||||
ldbl_max = ldexpl(1.0 - ldbl_eps / 2, LDBL_MAX_EXP);
|
||||
|
||||
/*
|
||||
* Special cases involving zeroes.
|
||||
@ -120,9 +120,11 @@ main(void)
|
||||
stest(nexttowardf, 0x1p-149f, f);
|
||||
stest(nexttowardl, ldbl_small, l);
|
||||
#undef stest
|
||||
}
|
||||
|
||||
printf("ok 1 - next\n");
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(eq_and_nan);
|
||||
ATF_TC_BODY(eq_and_nan, tc)
|
||||
{
|
||||
/*
|
||||
* `x == y' and NaN tests
|
||||
*/
|
||||
@ -133,33 +135,37 @@ main(void)
|
||||
testall(NAN, 42.0, NAN, 0);
|
||||
testall(42.0, NAN, NAN, 0);
|
||||
testall(NAN, NAN, NAN, 0);
|
||||
}
|
||||
|
||||
printf("ok 2 - next\n");
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(ordinary);
|
||||
ATF_TC_BODY(ordinary, tc)
|
||||
{
|
||||
/*
|
||||
* Tests where x is an ordinary normalized number
|
||||
*/
|
||||
testboth(1.0, 2.0, 1.0 + DBL_EPSILON, 0, );
|
||||
testboth(1.0, -INFINITY, 1.0 - DBL_EPSILON/2, 0, );
|
||||
testboth(1.0, -INFINITY, 1.0 - DBL_EPSILON / 2, 0, );
|
||||
testboth(1.0, 2.0, 1.0 + FLT_EPSILON, 0, f);
|
||||
testboth(1.0, -INFINITY, 1.0 - FLT_EPSILON/2, 0, f);
|
||||
testboth(1.0, -INFINITY, 1.0 - FLT_EPSILON / 2, 0, f);
|
||||
testboth(1.0, 2.0, 1.0 + ldbl_eps, 0, l);
|
||||
testboth(1.0, -INFINITY, 1.0 - ldbl_eps/2, 0, l);
|
||||
testboth(1.0, -INFINITY, 1.0 - ldbl_eps / 2, 0, l);
|
||||
|
||||
testboth(-1.0, 2.0, -1.0 + DBL_EPSILON/2, 0, );
|
||||
testboth(-1.0, 2.0, -1.0 + DBL_EPSILON / 2, 0, );
|
||||
testboth(-1.0, -INFINITY, -1.0 - DBL_EPSILON, 0, );
|
||||
testboth(-1.0, 2.0, -1.0 + FLT_EPSILON/2, 0, f);
|
||||
testboth(-1.0, 2.0, -1.0 + FLT_EPSILON / 2, 0, f);
|
||||
testboth(-1.0, -INFINITY, -1.0 - FLT_EPSILON, 0, f);
|
||||
testboth(-1.0, 2.0, -1.0 + ldbl_eps/2, 0, l);
|
||||
testboth(-1.0, 2.0, -1.0 + ldbl_eps / 2, 0, l);
|
||||
testboth(-1.0, -INFINITY, -1.0 - ldbl_eps, 0, l);
|
||||
|
||||
/* Cases where nextafter(...) != nexttoward(...) */
|
||||
test(nexttoward(1.0, 1.0 + ldbl_eps), 1.0 + DBL_EPSILON, 0);
|
||||
testf(nexttowardf(1.0, 1.0 + ldbl_eps), 1.0 + FLT_EPSILON, 0);
|
||||
testl(nexttowardl(1.0, 1.0 + ldbl_eps), 1.0 + ldbl_eps, 0);
|
||||
}
|
||||
|
||||
printf("ok 3 - next\n");
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(boundaries);
|
||||
ATF_TC_BODY(boundaries, tc)
|
||||
{
|
||||
/*
|
||||
* Tests at word boundaries, normalization boundaries, etc.
|
||||
*/
|
||||
@ -202,8 +208,18 @@ main(void)
|
||||
testboth(0x1p-16382L, -INFINITY,
|
||||
0x0.ffffffffffffffffffffffffffffp-16382L, ex_under, l);
|
||||
#endif
|
||||
}
|
||||
|
||||
printf("ok 4 - next\n");
|
||||
ATF_TC_WITHOUT_HEAD(overflow);
|
||||
ATF_TC_BODY(overflow, tc)
|
||||
{
|
||||
long double ldbl_max;
|
||||
/*
|
||||
* We can't use a compile-time constant here because gcc on
|
||||
* FreeBSD/i386 assumes long doubles are truncated to the
|
||||
* double format.
|
||||
*/
|
||||
ldbl_max = ldexpl(1.0 - ldbl_eps / 2, LDBL_MAX_EXP);
|
||||
|
||||
/*
|
||||
* Overflow tests
|
||||
@ -222,10 +238,6 @@ main(void)
|
||||
|
||||
testboth(ldbl_max, INFINITY, INFINITY, ex_over, l);
|
||||
testboth(INFINITY, 0.0, ldbl_max, 0, l);
|
||||
|
||||
printf("ok 5 - next\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -236,14 +248,13 @@ _testl(const char *exp, int line, long double actual, long double expected,
|
||||
|
||||
actual_except = fetestexcept(ALL_STD_EXCEPT);
|
||||
if (!fpequal(actual, expected)) {
|
||||
fprintf(stderr, "%d: %s returned %La, expecting %La\n",
|
||||
line, exp, actual, expected);
|
||||
abort();
|
||||
atf_tc_fail_check(__FILE__, line,
|
||||
"%s returned %La, expecting %La\n", exp, actual, expected);
|
||||
}
|
||||
if (actual_except != except) {
|
||||
fprintf(stderr, "%d: %s raised 0x%x, expecting 0x%x\n",
|
||||
line, exp, actual_except, except);
|
||||
abort();
|
||||
atf_tc_fail_check(__FILE__, line,
|
||||
"%s raised 0x%x, expecting 0x%x\n", exp, actual_except,
|
||||
except);
|
||||
}
|
||||
}
|
||||
|
||||
@ -263,3 +274,14 @@ idf(float x)
|
||||
{
|
||||
return (x);
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, zeros);
|
||||
ATF_TP_ADD_TC(tp, ordinary);
|
||||
ATF_TP_ADD_TC(tp, eq_and_nan);
|
||||
ATF_TP_ADD_TC(tp, boundaries);
|
||||
ATF_TP_ADD_TC(tp, overflow);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -33,13 +33,14 @@
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <assert.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
static void test_invalid(long double, long double);
|
||||
static void testl(long double, long double, long double, int);
|
||||
static void testd(double, double, double, int);
|
||||
@ -51,12 +52,9 @@ static void testf(float, float, float, int);
|
||||
testf(x, y, e_r, e_q); \
|
||||
} while (0)
|
||||
|
||||
int
|
||||
main(void)
|
||||
ATF_TC_WITHOUT_HEAD(rem1);
|
||||
ATF_TC_BODY(rem1, tc)
|
||||
{
|
||||
|
||||
printf("1..3\n");
|
||||
|
||||
test_invalid(0.0, 0.0);
|
||||
test_invalid(1.0, 0.0);
|
||||
test_invalid(INFINITY, 0.0);
|
||||
@ -72,15 +70,17 @@ main(void)
|
||||
test(3.0, 4, -1, 1);
|
||||
test(3.0, -4, -1, -1);
|
||||
testd(275 * 1193040, 275, 0, 1193040);
|
||||
test(4.5 * 7.5, 4.5, -2.25, 8); /* we should get the even one */
|
||||
test(4.5 * 7.5, 4.5, -2.25, 8); /* we should get the even one */
|
||||
testf(0x1.9044f6p-1, 0x1.ce662ep-1, -0x1.f109cp-4, 1);
|
||||
#if LDBL_MANT_DIG > 53
|
||||
testl(-0x1.23456789abcdefp-2000L, 0x1.fedcba987654321p-2000L,
|
||||
0x1.b72ea61d950c862p-2001L, -1);
|
||||
0x1.b72ea61d950c862p-2001L, -1);
|
||||
#endif
|
||||
}
|
||||
|
||||
printf("ok 1 - rem\n");
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(rem2);
|
||||
ATF_TC_BODY(rem2, tc)
|
||||
{
|
||||
/*
|
||||
* The actual quotient here is 864062210.50000003..., but
|
||||
* double-precision division gets -8.64062210.5, which rounds
|
||||
@ -91,20 +91,18 @@ main(void)
|
||||
0x1.fb3165b82de72p-333, -864062211);
|
||||
/* Even harder cases with greater exponent separation */
|
||||
test(0x1.fp100, 0x1.ep-40, -0x1.cp-41, 143165577);
|
||||
testd(-0x1.abcdefp120, 0x1.87654321p-120,
|
||||
-0x1.69c78ec4p-121, -63816414);
|
||||
|
||||
printf("ok 2 - rem\n");
|
||||
testd(-0x1.abcdefp120, 0x1.87654321p-120, -0x1.69c78ec4p-121,
|
||||
-63816414);
|
||||
}
|
||||
|
||||
ATF_TC_WITHOUT_HEAD(rem3);
|
||||
ATF_TC_BODY(rem3, tc)
|
||||
{
|
||||
test(0x1.66666cp+120, 0x1p+71, 0.0, 1476395008);
|
||||
testd(-0x1.0000000000003p+0, 0x1.0000000000003p+0, -0.0, -1);
|
||||
testl(-0x1.0000000000003p+0, 0x1.0000000000003p+0, -0.0, -1);
|
||||
testd(-0x1.0000000000001p-749, 0x1.4p-1072, 0x1p-1074, -1288490189);
|
||||
testl(-0x1.0000000000001p-749, 0x1.4p-1072, 0x1p-1074, -1288490189);
|
||||
|
||||
printf("ok 3 - rem\n");
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -114,22 +112,22 @@ test_invalid(long double x, long double y)
|
||||
|
||||
q = 0xdeadbeef;
|
||||
|
||||
assert(isnan(remainder(x, y)));
|
||||
assert(isnan(remquo(x, y, &q)));
|
||||
ATF_CHECK(isnan(remainder(x, y)));
|
||||
ATF_CHECK(isnan(remquo(x, y, &q)));
|
||||
#ifdef STRICT
|
||||
assert(q == 0xdeadbeef);
|
||||
ATF_CHECK(q == 0xdeadbeef);
|
||||
#endif
|
||||
|
||||
assert(isnan(remainderf(x, y)));
|
||||
assert(isnan(remquof(x, y, &q)));
|
||||
ATF_CHECK(isnan(remainderf(x, y)));
|
||||
ATF_CHECK(isnan(remquof(x, y, &q)));
|
||||
#ifdef STRICT
|
||||
assert(q == 0xdeadbeef);
|
||||
ATF_CHECK(q == 0xdeadbeef);
|
||||
#endif
|
||||
|
||||
assert(isnan(remainderl(x, y)));
|
||||
assert(isnan(remquol(x, y, &q)));
|
||||
ATF_CHECK(isnan(remainderl(x, y)));
|
||||
ATF_CHECK(isnan(remquol(x, y, &q)));
|
||||
#ifdef STRICT
|
||||
assert(q == 0xdeadbeef);
|
||||
ATF_CHECK(q == 0xdeadbeef);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -148,17 +146,17 @@ testl(long double x, long double y, long double expected_rem, int expected_quo)
|
||||
|
||||
q = random();
|
||||
rem = remainderl(x, y);
|
||||
assert(rem == expected_rem);
|
||||
assert(!signbit(rem) == !signbit(expected_rem));
|
||||
ATF_CHECK(rem == expected_rem);
|
||||
ATF_CHECK(!signbit(rem) == !signbit(expected_rem));
|
||||
rem = remquol(x, y, &q);
|
||||
assert(rem == expected_rem);
|
||||
assert(!signbit(rem) == !signbit(expected_rem));
|
||||
assert((q ^ expected_quo) >= 0); /* sign(q) == sign(expected_quo) */
|
||||
assert((q & 0x7) == (expected_quo & 0x7));
|
||||
ATF_CHECK(rem == expected_rem);
|
||||
ATF_CHECK(!signbit(rem) == !signbit(expected_rem));
|
||||
ATF_CHECK((q ^ expected_quo) >= 0); /* sign(q) == sign(expected_quo) */
|
||||
ATF_CHECK((q & 0x7) == (expected_quo & 0x7));
|
||||
if (q != 0) {
|
||||
assert((q > 0) ^ !(expected_quo > 0));
|
||||
ATF_CHECK((q > 0) ^ !(expected_quo > 0));
|
||||
q = abs(q);
|
||||
assert(q == (abs(expected_quo) & mask(q)));
|
||||
ATF_CHECK(q == (abs(expected_quo) & mask(q)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -170,17 +168,17 @@ testd(double x, double y, double expected_rem, int expected_quo)
|
||||
|
||||
q = random();
|
||||
rem = remainder(x, y);
|
||||
assert(rem == expected_rem);
|
||||
assert(!signbit(rem) == !signbit(expected_rem));
|
||||
ATF_CHECK(rem == expected_rem);
|
||||
ATF_CHECK(!signbit(rem) == !signbit(expected_rem));
|
||||
rem = remquo(x, y, &q);
|
||||
assert(rem == expected_rem);
|
||||
assert(!signbit(rem) == !signbit(expected_rem));
|
||||
assert((q ^ expected_quo) >= 0); /* sign(q) == sign(expected_quo) */
|
||||
assert((q & 0x7) == (expected_quo & 0x7));
|
||||
ATF_CHECK(rem == expected_rem);
|
||||
ATF_CHECK(!signbit(rem) == !signbit(expected_rem));
|
||||
ATF_CHECK((q ^ expected_quo) >= 0); /* sign(q) == sign(expected_quo) */
|
||||
ATF_CHECK((q & 0x7) == (expected_quo & 0x7));
|
||||
if (q != 0) {
|
||||
assert((q > 0) ^ !(expected_quo > 0));
|
||||
ATF_CHECK((q > 0) ^ !(expected_quo > 0));
|
||||
q = abs(q);
|
||||
assert(q == (abs(expected_quo) & mask(q)));
|
||||
ATF_CHECK(q == (abs(expected_quo) & mask(q)));
|
||||
}
|
||||
}
|
||||
|
||||
@ -192,16 +190,25 @@ testf(float x, float y, float expected_rem, int expected_quo)
|
||||
|
||||
q = random();
|
||||
rem = remainderf(x, y);
|
||||
assert(rem == expected_rem);
|
||||
assert(!signbit(rem) == !signbit(expected_rem));
|
||||
ATF_CHECK(rem == expected_rem);
|
||||
ATF_CHECK(!signbit(rem) == !signbit(expected_rem));
|
||||
rem = remquof(x, y, &q);
|
||||
assert(rem == expected_rem);
|
||||
assert(!signbit(rem) == !signbit(expected_rem));
|
||||
assert((q ^ expected_quo) >= 0); /* sign(q) == sign(expected_quo) */
|
||||
assert((q & 0x7) == (expected_quo & 0x7));
|
||||
ATF_CHECK(rem == expected_rem);
|
||||
ATF_CHECK(!signbit(rem) == !signbit(expected_rem));
|
||||
ATF_CHECK((q ^ expected_quo) >= 0); /* sign(q) == sign(expected_quo) */
|
||||
ATF_CHECK((q & 0x7) == (expected_quo & 0x7));
|
||||
if (q != 0) {
|
||||
assert((q > 0) ^ !(expected_quo > 0));
|
||||
ATF_CHECK((q > 0) ^ !(expected_quo > 0));
|
||||
q = abs(q);
|
||||
assert((q & mask(q)) == (abs(expected_quo) & mask(q)));
|
||||
ATF_CHECK((q & mask(q)) == (abs(expected_quo) & mask(q)));
|
||||
}
|
||||
}
|
||||
|
||||
ATF_TP_ADD_TCS(tp)
|
||||
{
|
||||
ATF_TP_ADD_TC(tp, rem1);
|
||||
ATF_TP_ADD_TC(tp, rem2);
|
||||
ATF_TP_ADD_TC(tp, rem3);
|
||||
|
||||
return (atf_no_error());
|
||||
}
|
||||
|
@ -32,6 +32,8 @@
|
||||
#include <complex.h>
|
||||
#include <fenv.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
/*
|
||||
* Implementations are permitted to define additional exception flags
|
||||
* not specified in the standard, so it is not necessarily true that
|
||||
@ -179,4 +181,13 @@ cfpequal_tol(long double complex x, long double complex y, long double tol,
|
||||
&& fpequal_tol(cimag(x), cimag(y), tol, flags));
|
||||
}
|
||||
|
||||
#define CHECK_FP_EXCEPTIONS(excepts, exceptmask) \
|
||||
ATF_CHECK_EQ_MSG((excepts), fetestexcept(exceptmask), \
|
||||
"unexpected exception flags: %#x not %#x", \
|
||||
fetestexcept(exceptmask), (excepts))
|
||||
#define CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, fmt, ...) \
|
||||
ATF_CHECK_EQ_MSG((excepts), fetestexcept(exceptmask), \
|
||||
"unexpected exception flags: got %#x not %#x " fmt, \
|
||||
fetestexcept(exceptmask), (excepts), __VA_ARGS__)
|
||||
|
||||
#endif /* _TEST_UTILS_H_ */
|
||||
|
@ -38,14 +38,11 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <fenv.h>
|
||||
#include <float.h>
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <atf-c.h>
|
||||
|
||||
#include "test-utils.h"
|
||||
|
||||
#pragma STDC FENV_ACCESS ON
|
||||
@ -66,8 +63,9 @@ __FBSDID("$FreeBSD$");
|
||||
#define test(func, x, result, exceptmask, excepts) do { \
|
||||
volatile long double _d = x; \
|
||||
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
|
||||
ATF_CHECK(fpequal((func)(_d), (result))); \
|
||||
ATF_CHECK(((void)(func), fetestexcept(exceptmask) == (excepts))); \
|
||||
ATF_CHECK(fpequal((func)(_d), (result))); \
|
||||
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
|
||||
#func, #x); \
|
||||
} while (0)
|
||||
|
||||
#define testall(prefix, x, result, exceptmask, excepts) do { \
|
||||
|
Loading…
Reference in New Issue
Block a user