1272343Sngie/* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */
2272343Sngie
3272343Sngie/*
4272343Sngie * Check result of fn(arg) is correct within the bounds.
5272343Sngie * Should be ok to do the checks using 'double' for 'float' functions.
6272343Sngie * On i386 float and double values are returned on the x87 stack and might
7272343Sngie * be out of range for the function - so save and print as 'long double'.
8272343Sngie * (otherwise you can get 'inf != inf' reported!)
9272343Sngie */
10272343Sngie#define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \
11272343Sngie	long double epsilon = epsilon_; \
12272343Sngie	long double expect = expect_; \
13272343Sngie	long double r = fn(arg); \
14272343Sngie	long double e = fabsl(r - expect); \
15272343Sngie	if (r != expect && e > epsilon) \
16272343Sngie		atf_tc_fail_nonfatal( \
17272343Sngie		    "subtest %u: " #fn "(%g) is %Lg (%.14La) " \
18272343Sngie		    "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \
19272343Sngie		    subtest, arg, r, r, expect, expect, e, e, epsilon); \
20272343Sngie    } while (0)
21272343Sngie
22272343Sngie/* Check that the result of fn(arg) is NaN */
23272343Sngie#ifndef __vax__
24272343Sngie#define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \
25272343Sngie	double r = fn(arg); \
26272343Sngie	if (!isnan(r)) \
27272343Sngie		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \
28272343Sngie		    subtest, arg, r); \
29272343Sngie    } while (0)
30272343Sngie#else
31272343Sngie/* vax doesn't support NaN */
32272343Sngie#define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg)
33272343Sngie#endif
34272343Sngie
35272343Sngie/* Check that the result of fn(arg) is +0.0 */
36272343Sngie#define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \
37272343Sngie	double r = fn(arg); \
38272343Sngie	if (fabs(r) > 0.0 || signbit(r) != 0) \
39272343Sngie		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \
40272343Sngie		    subtest, arg, r); \
41272343Sngie    } while (0)
42272343Sngie
43272343Sngie/* Check that the result of fn(arg) is -0.0 */
44272343Sngie#define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \
45272343Sngie	double r = fn(arg); \
46272343Sngie	if (fabs(r) > 0.0 || signbit(r) == 0) \
47272343Sngie		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \
48272343Sngie		    subtest, arg, r); \
49272343Sngie    } while (0)
50272343Sngie
51272343Sngie/* Some useful constants (for test vectors) */
52272343Sngie#ifndef __vax__	/* no NAN nor +/- INF on vax */
53272343Sngie#define T_LIBM_NAN	(0.0 / 0.0)
54272343Sngie#define T_LIBM_PLUS_INF	(+1.0 / 0.0)
55272343Sngie#define T_LIBM_MINUS_INF (-1.0 / 0.0)
56272343Sngie#endif
57272343Sngie
58272343Sngie/* One line definition of a simple test */
59272343Sngie#define ATF_LIBM_TEST(name, description) \
60272343SngieATF_TC(name); \
61272343SngieATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \
62272343SngieATF_TC_BODY(name, tc)
63