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:
Alex Richardson 2021-03-22 11:15:13 +00:00
parent aa05775ef0
commit 133bc64507
22 changed files with 859 additions and 860 deletions

View File

@ -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})

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -1,10 +0,0 @@
#!/bin/sh
# $FreeBSD$
cd `dirname $0`
executable=`basename $0 .t`
make $executable 2>&1 > /dev/null
exec ./$executable

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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());
}

View File

@ -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_ */

View File

@ -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 { \