xref: /minix3/tests/lib/libm/t_libm.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1*0a6a1f1dSLionel Sambuc /* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */
2*0a6a1f1dSLionel Sambuc 
3*0a6a1f1dSLionel Sambuc /*
4*0a6a1f1dSLionel Sambuc  * Check result of fn(arg) is correct within the bounds.
5*0a6a1f1dSLionel Sambuc  * Should be ok to do the checks using 'double' for 'float' functions.
6*0a6a1f1dSLionel Sambuc  * On i386 float and double values are returned on the x87 stack and might
7*0a6a1f1dSLionel Sambuc  * be out of range for the function - so save and print as 'long double'.
8*0a6a1f1dSLionel Sambuc  * (otherwise you can get 'inf != inf' reported!)
9*0a6a1f1dSLionel Sambuc  */
10*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \
11*0a6a1f1dSLionel Sambuc 	long double epsilon = epsilon_; \
12*0a6a1f1dSLionel Sambuc 	long double expect = expect_; \
13*0a6a1f1dSLionel Sambuc 	long double r = fn(arg); \
14*0a6a1f1dSLionel Sambuc 	long double e = fabsl(r - expect); \
15*0a6a1f1dSLionel Sambuc 	if (r != expect && e > epsilon) \
16*0a6a1f1dSLionel Sambuc 		atf_tc_fail_nonfatal( \
17*0a6a1f1dSLionel Sambuc 		    "subtest %u: " #fn "(%g) is %Lg (%.14La) " \
18*0a6a1f1dSLionel Sambuc 		    "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \
19*0a6a1f1dSLionel Sambuc 		    subtest, arg, r, r, expect, expect, e, e, epsilon); \
20*0a6a1f1dSLionel Sambuc     } while (0)
21*0a6a1f1dSLionel Sambuc 
22*0a6a1f1dSLionel Sambuc /* Check that the result of fn(arg) is NaN */
23*0a6a1f1dSLionel Sambuc #ifndef __vax__
24*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \
25*0a6a1f1dSLionel Sambuc 	double r = fn(arg); \
26*0a6a1f1dSLionel Sambuc 	if (!isnan(r)) \
27*0a6a1f1dSLionel Sambuc 		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \
28*0a6a1f1dSLionel Sambuc 		    subtest, arg, r); \
29*0a6a1f1dSLionel Sambuc     } while (0)
30*0a6a1f1dSLionel Sambuc #else
31*0a6a1f1dSLionel Sambuc /* vax doesn't support NaN */
32*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg)
33*0a6a1f1dSLionel Sambuc #endif
34*0a6a1f1dSLionel Sambuc 
35*0a6a1f1dSLionel Sambuc /* Check that the result of fn(arg) is +0.0 */
36*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \
37*0a6a1f1dSLionel Sambuc 	double r = fn(arg); \
38*0a6a1f1dSLionel Sambuc 	if (fabs(r) > 0.0 || signbit(r) != 0) \
39*0a6a1f1dSLionel Sambuc 		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \
40*0a6a1f1dSLionel Sambuc 		    subtest, arg, r); \
41*0a6a1f1dSLionel Sambuc     } while (0)
42*0a6a1f1dSLionel Sambuc 
43*0a6a1f1dSLionel Sambuc /* Check that the result of fn(arg) is -0.0 */
44*0a6a1f1dSLionel Sambuc #define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \
45*0a6a1f1dSLionel Sambuc 	double r = fn(arg); \
46*0a6a1f1dSLionel Sambuc 	if (fabs(r) > 0.0 || signbit(r) == 0) \
47*0a6a1f1dSLionel Sambuc 		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \
48*0a6a1f1dSLionel Sambuc 		    subtest, arg, r); \
49*0a6a1f1dSLionel Sambuc     } while (0)
50*0a6a1f1dSLionel Sambuc 
51*0a6a1f1dSLionel Sambuc /* Some useful constants (for test vectors) */
52*0a6a1f1dSLionel Sambuc #ifndef __vax__	/* no NAN nor +/- INF on vax */
53*0a6a1f1dSLionel Sambuc #define T_LIBM_NAN	(0.0 / 0.0)
54*0a6a1f1dSLionel Sambuc #define T_LIBM_PLUS_INF	(+1.0 / 0.0)
55*0a6a1f1dSLionel Sambuc #define T_LIBM_MINUS_INF (-1.0 / 0.0)
56*0a6a1f1dSLionel Sambuc #endif
57*0a6a1f1dSLionel Sambuc 
58*0a6a1f1dSLionel Sambuc /* One line definition of a simple test */
59*0a6a1f1dSLionel Sambuc #define ATF_LIBM_TEST(name, description) \
60*0a6a1f1dSLionel Sambuc ATF_TC(name); \
61*0a6a1f1dSLionel Sambuc ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \
62*0a6a1f1dSLionel Sambuc ATF_TC_BODY(name, tc)
63