Improve test messages for msun tests

Also print the mismatched values when numbers compare not equal.

Reviewed By:	dim
Differential Revision: https://reviews.freebsd.org/D29091
This commit is contained in:
Alex Richardson 2021-03-22 11:42:07 +00:00
parent b358534ab1
commit b424e0038a
16 changed files with 101 additions and 105 deletions

View File

@ -63,7 +63,7 @@ do { \
volatile long double complex _d = z; \ volatile long double complex _d = z; \
volatile type complex _r = result; \ volatile type complex _r = result; \
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
ATF_CHECK(cfpequal_cs((func)(_d), (_r), (checksign))); \ CHECK_CFPEQUAL_CS((func)(_d), (_r), (checksign)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
#func, #z); \ #func, #z); \
} while (0) } while (0)
@ -76,9 +76,8 @@ do { \
/* Test within a given tolerance. */ /* Test within a given tolerance. */
#define test_tol(func, z, result, tol) do { \ #define test_tol(func, z, result, tol) do { \
volatile long double complex _d = z; \ CHECK_CFPEQUAL_TOL((func)(z), (result), (tol), \
ATF_CHECK(cfpequal_tol((func)(_d), (result), (tol), \ FPE_ABS_ZERO | CS_BOTH); \
FPE_ABS_ZERO | CS_BOTH)); \
} while (0) } while (0)
/* Test all the functions that compute cexp(x). */ /* Test all the functions that compute cexp(x). */

View File

@ -82,12 +82,12 @@ ATF_TC_BODY(main, tc)
__imag__ in = tests[2 * i + 1]; __imag__ in = tests[2 * i + 1];
__imag__ expected = -cimag(in); __imag__ expected = -cimag(in);
ATF_REQUIRE(fpequal(libcrealf(in), __real__ in)); ATF_REQUIRE(fpequal_cs(libcrealf(in), __real__ in, true));
ATF_REQUIRE(fpequal(libcreal(in), __real__ in)); ATF_REQUIRE(fpequal_cs(libcreal(in), __real__ in, true));
ATF_REQUIRE(fpequal(libcreall(in), __real__ in)); ATF_REQUIRE(fpequal_cs(libcreall(in), __real__ in, true));
ATF_REQUIRE(fpequal(libcimagf(in), __imag__ in)); ATF_REQUIRE(fpequal_cs(libcimagf(in), __imag__ in, true));
ATF_REQUIRE(fpequal(libcimag(in), __imag__ in)); ATF_REQUIRE(fpequal_cs(libcimag(in), __imag__ in, true));
ATF_REQUIRE(fpequal(libcimagl(in), __imag__ in)); ATF_REQUIRE(fpequal_cs(libcimagl(in), __imag__ in, true));
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT));
ATF_REQUIRE_MSG( ATF_REQUIRE_MSG(

View File

@ -67,12 +67,7 @@ _csqrt(long double complex d)
* Compare d1 and d2 using special rules: NaN == NaN and +0 != -0. * Compare d1 and d2 using special rules: NaN == NaN and +0 != -0.
* Fail an assertion if they differ. * Fail an assertion if they differ.
*/ */
static void #define assert_equal(d1, d2) CHECK_CFPEQUAL_CS(d1, d2, CS_BOTH)
assert_equal(long double complex d1, long double complex d2)
{
ATF_CHECK(cfpequal(d1, d2));
}
/* /*
* Test csqrt for some finite arguments where the answer is exact. * Test csqrt for some finite arguments where the answer is exact.

View File

@ -62,11 +62,7 @@ __FBSDID("$FreeBSD$");
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \ debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \ creall(_d), cimagl(_d), creall(result), cimagl(result)); \
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \ ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
volatile long double complex _r = (func)(_d); \ CHECK_CFPEQUAL_CS((func)(_d), (result), (checksign)); \
ATF_CHECK_MSG(cfpequal_cs(_r, (result), (checksign)), \
"%s (%Lg + %Lg I) != expected (%Lg + %Lg I)", \
__XSTRING((func)(_d)), creall(_r), cimagl(_r), \
creall(result), cimagl(result)); \
volatile int _e = fetestexcept(exceptmask); \ volatile int _e = fetestexcept(exceptmask); \
ATF_CHECK_MSG(_e == (excepts), \ ATF_CHECK_MSG(_e == (excepts), \
"%s fetestexcept(%s) (%#x) != %#x", __XSTRING(func), \ "%s fetestexcept(%s) (%#x) != %#x", __XSTRING(func), \
@ -79,10 +75,9 @@ __FBSDID("$FreeBSD$");
* of <format>_EPSILON. * of <format>_EPSILON.
*/ */
#define test_p_tol(func, z, result, tol) do { \ #define test_p_tol(func, z, result, tol) do { \
volatile long double complex _d = z; \
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \ debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \ creall(z), cimagl(z), creall(result), cimagl(result)); \
ATF_CHECK(cfpequal_tol((func)(_d), (result), (tol), FPE_ABS_ZERO)); \ CHECK_CFPEQUAL_TOL((func)(z), (result), (tol), FPE_ABS_ZERO); \
} while (0) } while (0)
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */ /* These wrappers apply the identities f(conj(z)) = conj(f(z)). */

View File

@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$");
#define test(func, x, result, exceptmask, excepts) do { \ #define test(func, x, result, exceptmask, excepts) do { \
volatile long double _d = x; \ volatile long double _d = x; \
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
ATF_CHECK(fpequal((func)(_d), (result))); \ CHECK_FPEQUAL((func)(_d), (result)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
#func, #x); \ #func, #x); \
} while (0) } while (0)

View File

@ -248,7 +248,7 @@ ATF_TC_BODY(fegsetexceptflag, tc)
fexcept_t flag; fexcept_t flag;
int excepts, i; int excepts, i;
ATF_CHECK_EQ(0, fetestexcept(FE_ALL_EXCEPT)); CHECK_FP_EXCEPTIONS(0, FE_ALL_EXCEPT);
for (i = 0; i < 1 << NEXCEPTS; i++) { for (i = 0; i < 1 << NEXCEPTS; i++) {
excepts = std_except_sets[i]; excepts = std_except_sets[i];

View File

@ -55,7 +55,7 @@ __FBSDID("$FreeBSD$");
#define test(func, x, y, z, result, exceptmask, excepts) do { \ #define test(func, x, y, z, result, exceptmask, excepts) do { \
volatile long double _vx = (x), _vy = (y), _vz = (z); \ volatile long double _vx = (x), _vy = (y), _vz = (z); \
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \ ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
ATF_CHECK(fpequal((func)(_vx, _vy, _vz), (result))); \ CHECK_FPEQUAL((func)(_vx, _vy, _vz), (result)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
#func, #x); \ #func, #x); \
} while (0) } while (0)

View File

@ -51,7 +51,7 @@ __FBSDID("$FreeBSD$");
long double __result = func((__x), (__y)); \ long double __result = func((__x), (__y)); \
CHECK_FP_EXCEPTIONS_MSG(0, ALL_STD_EXCEPT, \ CHECK_FP_EXCEPTIONS_MSG(0, ALL_STD_EXCEPT, \
#func "(%.20Lg, %.20Lg) rmode%d", (x), (y), rmode); \ #func "(%.20Lg, %.20Lg) rmode%d", (x), (y), rmode); \
ATF_CHECK_MSG(fpequal(__result, (expected)), \ ATF_CHECK_MSG(fpequal_cs(__result, (expected), true), \
#func "(%.20Lg, %.20Lg) rmode%d = %.20Lg, expected %.20Lg\n", \ #func "(%.20Lg, %.20Lg) rmode%d = %.20Lg, expected %.20Lg\n", \
(x), (y), rmode, __result, (expected)); \ (x), (y), rmode, __result, (expected)); \
} while (0) } while (0)

View File

@ -61,7 +61,7 @@ __FBSDID("$FreeBSD$");
debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \ debug(" testing %s(%Lg + %Lg I) == %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \ creall(_d), cimagl(_d), creall(result), cimagl(result)); \
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
ATF_CHECK(cfpequal_cs((func)(_d), (result), (checksign))); \ CHECK_CFPEQUAL_CS((func)(_d), (result), (checksign)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
#func, #z); \ #func, #z); \
} while (0) } while (0)
@ -71,10 +71,9 @@ __FBSDID("$FreeBSD$");
* in ulps. * in ulps.
*/ */
#define test_p_tol(func, z, result, tol) do { \ #define test_p_tol(func, z, result, tol) do { \
volatile long double complex _d = z; \
debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \ debug(" testing %s(%Lg + %Lg I) ~= %Lg + %Lg I\n", #func, \
creall(_d), cimagl(_d), creall(result), cimagl(result)); \ creall(z), cimagl(z), creall(result), cimagl(result)); \
ATF_CHECK(cfpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \ CHECK_CFPEQUAL_TOL((func)(z), (result), (tol), CS_BOTH); \
} while (0) } while (0)
/* These wrappers apply the identities f(conj(z)) = conj(f(z)). */ /* These wrappers apply the identities f(conj(z)) = conj(f(z)). */

View File

@ -54,7 +54,7 @@ __FBSDID("$FreeBSD$");
#define test_tol(func, x, result, tol, excepts) do { \ #define test_tol(func, x, result, tol, excepts) do { \
volatile long double _in = (x), _out = (result); \ volatile long double _in = (x), _out = (result); \
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
ATF_CHECK(fpequal_tol(func(_in), _out, (tol), CS_BOTH)); \ CHECK_FPEQUAL_TOL(func(_in), _out, (tol), CS_BOTH); \
CHECK_FP_EXCEPTIONS_MSG(excepts, ALL_STD_EXCEPT, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, ALL_STD_EXCEPT, "for %s(%s)", \
#func, #x); \ #func, #x); \
} while (0) } while (0)
@ -84,7 +84,7 @@ __FBSDID("$FreeBSD$");
#define test2_tol(func, y, x, result, tol, excepts) do { \ #define test2_tol(func, y, x, result, tol, excepts) do { \
volatile long double _iny = (y), _inx = (x), _out = (result); \ volatile long double _iny = (y), _inx = (x), _out = (result); \
ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ ATF_REQUIRE_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
ATF_CHECK(fpequal_tol(func(_iny, _inx), _out, (tol), CS_BOTH)); \ CHECK_FPEQUAL_TOL(func(_iny, _inx), _out, (tol), CS_BOTH); \
CHECK_FP_EXCEPTIONS_MSG(excepts, ALL_STD_EXCEPT, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, ALL_STD_EXCEPT, "for %s(%s)", \
#func, #x); \ #func, #x); \
} while (0) } while (0)

View File

@ -61,7 +61,7 @@ __FBSDID("$FreeBSD$");
#define test(func, x, result, exceptmask, excepts) do { \ #define test(func, x, result, exceptmask, excepts) do { \
volatile long double _d = x; \ volatile long double _d = x; \
ATF_CHECK_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \ ATF_CHECK_EQ(0, feclearexcept(FE_ALL_EXCEPT)); \
ATF_CHECK(fpequal((func)(_d), (result))); \ CHECK_FPEQUAL((func)(_d), (result)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
#func, #x); \ #func, #x); \
} while (0) } while (0)
@ -69,7 +69,7 @@ __FBSDID("$FreeBSD$");
#define test_tol(func, z, result, tol) do { \ #define test_tol(func, z, result, tol) do { \
volatile long double _d = z; \ volatile long double _d = z; \
debug(" testing %6s(%15La) ~= % .36Le\n", #func, _d, result); \ debug(" testing %6s(%15La) ~= % .36Le\n", #func, _d, result); \
ATF_CHECK(fpequal_tol((func)(_d), (result), (tol), CS_BOTH)); \ CHECK_FPEQUAL_TOL((func)(_d), (result), (tol), CS_BOTH); \
} while (0) } while (0)
/* Test all the functions that compute log(x). */ /* Test all the functions that compute log(x). */
@ -207,7 +207,7 @@ ATF_TC_BODY(accuracy_tests, tc)
1.29556709996247903756734359702926363e0L }, 1.29556709996247903756734359702926363e0L },
{ 19.75 * 0x1p100, { 19.75 * 0x1p100,
1.043037807481771029244272863419411534e2L, 1.043037807481771029244272863419411534e2L,
7.229787154734166181706169344438271459e1L, 72.29787154734166181706169344438271459357255439172762452L,
3.139856666636059855894123306947856631e1L }, 3.139856666636059855894123306947856631e1L },
}; };
unsigned i; unsigned i;

View File

@ -42,14 +42,12 @@ __FBSDID("$FreeBSD$");
#include "test-utils.h" #include "test-utils.h"
/*
* 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 { \ #define test(func, x, result, excepts) do { \
volatile double _d = x; \
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \ ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
ATF_CHECK((func)(_d) == (result) || fetestexcept(FE_INVALID)); \ long long _r = (func)(x); \
ATF_CHECK_MSG(_r == (result) || fetestexcept(FE_INVALID), \
#func "(%Lg) returned %lld, expected %lld", (long double)x, _r, \
(long long)(result)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, FE_ALL_EXCEPT & ALL_STD_EXCEPT, \ CHECK_FP_EXCEPTIONS_MSG(excepts, FE_ALL_EXCEPT & ALL_STD_EXCEPT, \
"for %s(%s)", #func, #x); \ "for %s(%s)", #func, #x); \
} while (0) } while (0)

View File

@ -97,16 +97,16 @@ test_nearby(int testindex)
in = tests[testindex].in; in = tests[testindex].in;
out = get_output(testindex, i, 0); out = get_output(testindex, i, 0);
ATF_CHECK(fpequal(out, libnearbyintf(in))); CHECK_FPEQUAL(out, libnearbyintf(in));
ATF_CHECK(fpequal(out, nearbyint(in))); CHECK_FPEQUAL(out, nearbyint(in));
ATF_CHECK(fpequal(out, nearbyintl(in))); CHECK_FPEQUAL(out, nearbyintl(in));
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
in = -tests[testindex].in; in = -tests[testindex].in;
out = get_output(testindex, i, 1); out = get_output(testindex, i, 1);
ATF_CHECK(fpequal(out, nearbyintf(in))); CHECK_FPEQUAL(out, nearbyintf(in));
ATF_CHECK(fpequal(out, nearbyint(in))); CHECK_FPEQUAL(out, nearbyint(in));
ATF_CHECK(fpequal(out, nearbyintl(in))); CHECK_FPEQUAL(out, nearbyintl(in));
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
} }
} }
@ -130,24 +130,24 @@ test_modf(int testindex)
isinf(ipart_expected) ? 0.0 : in - ipart_expected, in); isinf(ipart_expected) ? 0.0 : in - ipart_expected, in);
ipartl = ipart = ipartf = 42.0; ipartl = ipart = ipartf = 42.0;
ATF_CHECK(fpequal(out, modff(in, &ipartf))); CHECK_FPEQUAL(out, modff(in, &ipartf));
ATF_CHECK(fpequal(ipart_expected, ipartf)); CHECK_FPEQUAL(ipart_expected, ipartf);
ATF_CHECK(fpequal(out, modf(in, &ipart))); CHECK_FPEQUAL(out, modf(in, &ipart));
ATF_CHECK(fpequal(ipart_expected, ipart)); CHECK_FPEQUAL(ipart_expected, ipart);
ATF_CHECK(fpequal(out, modfl(in, &ipartl))); CHECK_FPEQUAL(out, modfl(in, &ipartl));
ATF_CHECK(fpequal(ipart_expected, ipartl)); CHECK_FPEQUAL(ipart_expected, ipartl);
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
in = -in; in = -in;
ipart_expected = -ipart_expected; ipart_expected = -ipart_expected;
out = -out; out = -out;
ipartl = ipart = ipartf = 42.0; ipartl = ipart = ipartf = 42.0;
ATF_CHECK(fpequal(out, modff(in, &ipartf))); CHECK_FPEQUAL(out, modff(in, &ipartf));
ATF_CHECK(fpequal(ipart_expected, ipartf)); CHECK_FPEQUAL(ipart_expected, ipartf);
ATF_CHECK(fpequal(out, modf(in, &ipart))); CHECK_FPEQUAL(out, modf(in, &ipart));
ATF_CHECK(fpequal(ipart_expected, ipart)); CHECK_FPEQUAL(ipart_expected, ipart);
ATF_CHECK(fpequal(out, modfl(in, &ipartl))); CHECK_FPEQUAL(out, modfl(in, &ipartl));
ATF_CHECK(fpequal(ipart_expected, ipartl)); CHECK_FPEQUAL(ipart_expected, ipartl);
CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT); CHECK_FP_EXCEPTIONS(0, ALL_STD_EXCEPT);
} }
} }

View File

@ -247,7 +247,7 @@ _testl(const char *exp, int line, long double actual, long double expected,
int actual_except; int actual_except;
actual_except = fetestexcept(ALL_STD_EXCEPT); actual_except = fetestexcept(ALL_STD_EXCEPT);
if (!fpequal(actual, expected)) { if (!fpequal_cs(actual, expected, true)) {
atf_tc_fail_check(__FILE__, line, atf_tc_fail_check(__FILE__, line,
"%s returned %La, expecting %La\n", exp, actual, expected); "%s returned %La, expecting %La\n", exp, actual, expected);
} }

View File

@ -31,6 +31,7 @@
#include <complex.h> #include <complex.h>
#include <fenv.h> #include <fenv.h>
#include <float.h>
#include <atf-c.h> #include <atf-c.h>
@ -90,34 +91,21 @@ CMPLXL(long double x, long double y)
} }
#endif #endif
static int fpequal(long double, long double) __used;
static int cfpequal(long double complex, long double complex) __used;
static int cfpequal_cs(long double complex, long double complex,
int) __used;
static int cfpequal_tol(long double complex, long double complex,
long double, unsigned int) __used;
/* /*
* Compare d1 and d2 using special rules: NaN == NaN and +0 != -0. * The compiler-rt fp128 builtins do not update FP exceptions.
* Fail an assertion if they differ. * See https://llvm.org/PR34126
*/ */
static int
fpequal(long double d1, long double d2)
{
if (d1 != d2) static int cfpequal(long double complex, long double complex) __used;
return (isnan(d1) && isnan(d2));
return (copysignl(1.0, d1) == copysignl(1.0, d2));
}
/* /*
* Determine whether x and y are equal, with two special rules: * Determine whether x and y are equal, with two special rules:
* +0.0 != -0.0 * +0.0 != -0.0
* NaN == NaN * NaN == NaN
* If checksign is 0, we compare the absolute values instead. * If checksign is false, we compare the absolute values instead.
*/ */
static int static inline int
fpequal_cs(long double x, long double y, int checksign) fpequal_cs(long double x, long double y, bool checksign)
{ {
if (isnan(x) && isnan(y)) if (isnan(x) && isnan(y))
return (1); return (1);
@ -127,7 +115,7 @@ fpequal_cs(long double x, long double y, int checksign)
return (fabsl(x) == fabsl(y)); return (fabsl(x) == fabsl(y));
} }
static int static inline int
fpequal_tol(long double x, long double y, long double tol, fpequal_tol(long double x, long double y, long double tol,
unsigned int flags) unsigned int flags)
{ {
@ -158,32 +146,54 @@ fpequal_tol(long double x, long double y, long double tol,
return (ret); return (ret);
} }
static int #define CHECK_FPEQUAL(x, y) CHECK_FPEQUAL_CS(x, y, true)
#define CHECK_FPEQUAL_CS(x, y, checksign) do { \
long double _x = x; \
long double _y = y; \
ATF_CHECK_MSG(fpequal_cs(_x, _y, checksign), \
"%s (%.25Lg) ~= %s (%.25Lg)", #x, _x, #y, _y); \
} while (0)
#define CHECK_FPEQUAL_TOL(x, y, tol, flags) do { \
long double _x = x; \
long double _y = y; \
bool eq = fpequal_tol(_x, _y, tol, flags); \
long double _diff = eq ? 0.0L : fabsl(_x - _y); \
ATF_CHECK_MSG(eq, "%s (%.25Lg) ~= %s (%.25Lg), diff=%Lg, maxdiff=%Lg,", \
#x, _x, #y, _y, _diff, fabsl(_y * tol)); \
} while (0)
static inline int
cfpequal(long double complex d1, long double complex d2) cfpequal(long double complex d1, long double complex d2)
{ {
return (fpequal(creall(d1), creall(d2)) && return (fpequal_cs(creall(d1), creall(d2), true) &&
fpequal(cimagl(d1), cimagl(d2))); fpequal_cs(cimagl(d1), cimagl(d2), true));
} }
static int #define CHECK_CFPEQUAL_CS(x, y, checksign) do { \
cfpequal_cs(long double complex x, long double complex y, int checksign) long double _x = x; \
{ long double _y = y; \
return (fpequal_cs(creal(x), creal(y), checksign) bool equal_cs = \
&& fpequal_cs(cimag(x), cimag(y), checksign)); fpequal_cs(creal(_x), creal(_y), (checksign & CS_REAL) != 0) && \
} fpequal_cs(cimag(_x), cimag(_y), (checksign & CS_IMAG) != 0); \
ATF_CHECK_MSG(equal_cs, "%s (%Lg + %Lg I) ~= %s (%Lg + %Lg I)", \
#x, creall(_x), cimagl(_x), #y, creall(_y), cimagl(_y)); \
} while (0)
static int #define CHECK_CFPEQUAL_TOL(x, y, tol, flags) do { \
cfpequal_tol(long double complex x, long double complex y, long double tol, long double _x = x; \
unsigned int flags) long double _y = y; \
{ bool equal_tol = (fpequal_tol(creal(_x), creal(_y), tol, flags) && \
return (fpequal_tol(creal(x), creal(y), tol, flags) fpequal_tol(cimag(_x), cimag(_y), tol, flags)); \
&& fpequal_tol(cimag(x), cimag(y), tol, flags)); ATF_CHECK_MSG(equal_tol, "%s (%Lg + %Lg I) ~= %s (%Lg + %Lg I)", \
} #x, creall(_x), cimagl(_x), #y, creall(_y), cimagl(_y)); \
} while (0)
#define CHECK_FP_EXCEPTIONS(excepts, exceptmask) \ #define CHECK_FP_EXCEPTIONS(excepts, exceptmask) \
ATF_CHECK_EQ_MSG((excepts), fetestexcept(exceptmask), \ ATF_CHECK_EQ_MSG((excepts), fetestexcept(exceptmask), \
"unexpected exception flags: %#x not %#x", \ "unexpected exception flags: got %#x not %#x", \
fetestexcept(exceptmask), (excepts)) fetestexcept(exceptmask), (excepts))
#define CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, fmt, ...) \ #define CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, fmt, ...) \
ATF_CHECK_EQ_MSG((excepts), fetestexcept(exceptmask), \ ATF_CHECK_EQ_MSG((excepts), fetestexcept(exceptmask), \

View File

@ -63,7 +63,7 @@ __FBSDID("$FreeBSD$");
#define test(func, x, result, exceptmask, excepts) do { \ #define test(func, x, result, exceptmask, excepts) do { \
volatile long double _d = x; \ volatile long double _d = x; \
ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \ ATF_CHECK(feclearexcept(FE_ALL_EXCEPT) == 0); \
ATF_CHECK(fpequal((func)(_d), (result))); \ CHECK_FPEQUAL((func)(_d), (result)); \
CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \ CHECK_FP_EXCEPTIONS_MSG(excepts, exceptmask, "for %s(%s)", \
#func, #x); \ #func, #x); \
} while (0) } while (0)