xref: /freebsd/contrib/netbsd-tests/lib/libm/t_libm.h (revision 1ec3feb64826d2a43d41e74684690985bf20e71c)
1*1ec3feb6SAlex Richardson /* $NetBSD: t_libm.h,v 1.7 2018/11/07 03:59:36 riastradh Exp $ */
257718be8SEnji Cooper 
357718be8SEnji Cooper /*
457718be8SEnji Cooper  * Check result of fn(arg) is correct within the bounds.
557718be8SEnji Cooper  * Should be ok to do the checks using 'double' for 'float' functions.
657718be8SEnji Cooper  * On i386 float and double values are returned on the x87 stack and might
757718be8SEnji Cooper  * be out of range for the function - so save and print as 'long double'.
857718be8SEnji Cooper  * (otherwise you can get 'inf != inf' reported!)
957718be8SEnji Cooper  */
1057718be8SEnji Cooper #define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \
1157718be8SEnji Cooper 	long double epsilon = epsilon_; \
1257718be8SEnji Cooper 	long double expect = expect_; \
1357718be8SEnji Cooper 	long double r = fn(arg); \
14*1ec3feb6SAlex Richardson 	long double e = fabsl((r - expect)/expect); \
15*1ec3feb6SAlex Richardson 	if (!(r == expect || e <= epsilon)) \
1657718be8SEnji Cooper 		atf_tc_fail_nonfatal( \
1757718be8SEnji Cooper 		    "subtest %u: " #fn "(%g) is %Lg (%.14La) " \
1857718be8SEnji Cooper 		    "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \
1957718be8SEnji Cooper 		    subtest, arg, r, r, expect, expect, e, e, epsilon); \
2057718be8SEnji Cooper     } while (0)
2157718be8SEnji Cooper 
2257718be8SEnji Cooper /* Check that the result of fn(arg) is NaN */
2357718be8SEnji Cooper #ifndef __vax__
2457718be8SEnji Cooper #define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \
2557718be8SEnji Cooper 	double r = fn(arg); \
2657718be8SEnji Cooper 	if (!isnan(r)) \
2757718be8SEnji Cooper 		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \
2857718be8SEnji Cooper 		    subtest, arg, r); \
2957718be8SEnji Cooper     } while (0)
3057718be8SEnji Cooper #else
3157718be8SEnji Cooper /* vax doesn't support NaN */
3257718be8SEnji Cooper #define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg)
3357718be8SEnji Cooper #endif
3457718be8SEnji Cooper 
3557718be8SEnji Cooper /* Check that the result of fn(arg) is +0.0 */
3657718be8SEnji Cooper #define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \
3757718be8SEnji Cooper 	double r = fn(arg); \
3857718be8SEnji Cooper 	if (fabs(r) > 0.0 || signbit(r) != 0) \
3957718be8SEnji Cooper 		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \
4057718be8SEnji Cooper 		    subtest, arg, r); \
4157718be8SEnji Cooper     } while (0)
4257718be8SEnji Cooper 
4357718be8SEnji Cooper /* Check that the result of fn(arg) is -0.0 */
4457718be8SEnji Cooper #define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \
4557718be8SEnji Cooper 	double r = fn(arg); \
4657718be8SEnji Cooper 	if (fabs(r) > 0.0 || signbit(r) == 0) \
4757718be8SEnji Cooper 		atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \
4857718be8SEnji Cooper 		    subtest, arg, r); \
4957718be8SEnji Cooper     } while (0)
5057718be8SEnji Cooper 
5157718be8SEnji Cooper /* Some useful constants (for test vectors) */
5257718be8SEnji Cooper #ifndef __vax__	/* no NAN nor +/- INF on vax */
5357718be8SEnji Cooper #define T_LIBM_NAN	(0.0 / 0.0)
5457718be8SEnji Cooper #define T_LIBM_PLUS_INF	(+1.0 / 0.0)
5557718be8SEnji Cooper #define T_LIBM_MINUS_INF (-1.0 / 0.0)
5657718be8SEnji Cooper #endif
5757718be8SEnji Cooper 
5857718be8SEnji Cooper /* One line definition of a simple test */
5957718be8SEnji Cooper #define ATF_LIBM_TEST(name, description) \
6057718be8SEnji Cooper ATF_TC(name); \
6157718be8SEnji Cooper ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \
6257718be8SEnji Cooper ATF_TC_BODY(name, tc)
63