Module Name: src Committed By: martin Date: Mon May 20 12:21:42 UTC 2013
Modified Files: src/tests/lib/libm: t_scalbn.c Log Message: Add a few test cases to test "ordinary" values with the various scalbn variants. While there, make some spuriously failing tests print out the broken values on failure. To generate a diff of this commit: cvs rdiff -u -r1.7 -r1.8 src/tests/lib/libm/t_scalbn.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/tests/lib/libm/t_scalbn.c diff -u src/tests/lib/libm/t_scalbn.c:1.7 src/tests/lib/libm/t_scalbn.c:1.8 --- src/tests/lib/libm/t_scalbn.c:1.7 Tue Sep 13 07:07:32 2011 +++ src/tests/lib/libm/t_scalbn.c Mon May 20 12:21:42 2013 @@ -1,4 +1,4 @@ -/* $NetBSD: t_scalbn.c,v 1.7 2011/09/13 07:07:32 jruoho Exp $ */ +/* $NetBSD: t_scalbn.c,v 1.8 2013/05/20 12:21:42 martin Exp $ */ /*- * Copyright (c) 2011 The NetBSD Foundation, Inc. @@ -29,18 +29,68 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include <sys/cdefs.h> -__RCSID("$NetBSD: t_scalbn.c,v 1.7 2011/09/13 07:07:32 jruoho Exp $"); +__RCSID("$NetBSD: t_scalbn.c,v 1.8 2013/05/20 12:21:42 martin Exp $"); #include <math.h> #include <limits.h> +#include <float.h> +#include <errno.h> #include <atf-c.h> static const int exps[] = { 0, 1, -1, 100, -100 }; +/* tests here do not require specific precision, so we just use double */ +struct testcase { + int exp; + double inval; + double result; + int error; +}; +struct testcase test_vals[] = { + { 0, 1.00085, 1.00085, 0 }, + { 0, 0.99755, 0.99755, 0 }, + { 0, -1.00085, -1.00085, 0 }, + { 0, -0.99755, -0.99755, 0 }, + { 1, 1.00085, 2.0* 1.00085, 0 }, + { 1, 0.99755, 2.0* 0.99755, 0 }, + { 1, -1.00085, 2.0* -1.00085, 0 }, + { 1, -0.99755, 2.0* -0.99755, 0 }, + + /* + * We could add more corner test cases here, but we would have to + * add some ifdefs for the exact format and use a reliable + * generator program - bail for now and only do trivial stuff above. + */ +}; + /* * scalbn(3) */ +ATF_TC(scalbn_val); +ATF_TC_HEAD(scalbn_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbn() for a few values"); +} + +ATF_TC_BODY(scalbn_val, tc) +{ + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + double rv; + + for (i = 0; i < tcnt; i++) { + rv = scalbn(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*DBL_EPSILON, + "test %zu: return value %g instead of %g (difference %g)", + i, rv, tests[i].result, tests[i].result-rv); + } +} + ATF_TC(scalbn_nan); ATF_TC_HEAD(scalbn_nan, tc) { @@ -113,7 +163,9 @@ ATF_TC_BODY(scalbn_ldexp, tc) for (i = 0; i < __arraycount(exps); i++) { y = scalbn(x, exps[i]); - ATF_CHECK(y == ldexp(x, exps[i])); + ATF_CHECK_MSG(y == ldexp(x, exps[i]), "test %zu: exponent=%d, " + "y=%g, expected %g (diff: %g)", i, exps[i], y, + ldexp(x, exps[i]), y - ldexp(x, exps[i])); } #endif #endif @@ -168,6 +220,30 @@ ATF_TC_BODY(scalbn_zero_pos, tc) /* * scalbnf(3) */ +ATF_TC(scalbnf_val); +ATF_TC_HEAD(scalbnf_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnf() for a few values"); +} + +ATF_TC_BODY(scalbnf_val, tc) +{ + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + double rv; + + for (i = 0; i < tcnt; i++) { + rv = scalbnf(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabs(rv-tests[i].result)<2.0*FLT_EPSILON, + "test %zu: return value %g instead of %g (difference %g)", + i, rv, tests[i].result, tests[i].result-rv); + } +} + ATF_TC(scalbnf_nan); ATF_TC_HEAD(scalbnf_nan, tc) { @@ -240,7 +316,9 @@ ATF_TC_BODY(scalbnf_ldexpf, tc) for (i = 0; i < __arraycount(exps); i++) { y = scalbnf(x, exps[i]); - ATF_CHECK(y == ldexpf(x, exps[i])); + ATF_CHECK_MSG(y == ldexpf(x, exps[i]), + "test %zu: exponent=%d, y=%g ldexpf returns %g (diff: %g)", + i, exps[i], y, ldexpf(x, exps[i]), y-ldexpf(x, exps[i])); } #endif #endif @@ -295,6 +373,34 @@ ATF_TC_BODY(scalbnf_zero_pos, tc) /* * scalbnl(3) */ +ATF_TC(scalbnl_val); +ATF_TC_HEAD(scalbnl_val, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test scalbnl() for a few values"); +} + +ATF_TC_BODY(scalbnl_val, tc) +{ +#ifndef __HAVE_LONG_DOUBLE + atf_tc_skip("Requires long double support"); +#else + const struct testcase *tests = test_vals; + const size_t tcnt = __arraycount(test_vals); + size_t i; + long double rv; + + for (i = 0; i < tcnt; i++) { + rv = scalbnl(tests[i].inval, tests[i].exp); + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: errno %d instead of %d", i, errno, + tests[i].error); + ATF_CHECK_MSG(fabsl(rv-(long double)tests[i].result)<2.0*LDBL_EPSILON, + "test %zu: return value %Lg instead of %Lg (difference %Lg)", + i, rv, (long double)tests[i].result, (long double)tests[i].result-rv); + } +#endif +} + ATF_TC(scalbnl_nan); ATF_TC_HEAD(scalbnl_nan, tc) { @@ -423,6 +529,7 @@ ATF_TC_BODY(scalbnl_zero_pos, tc) ATF_TP_ADD_TCS(tp) { + ATF_TP_ADD_TC(tp, scalbn_val); ATF_TP_ADD_TC(tp, scalbn_nan); ATF_TP_ADD_TC(tp, scalbn_inf_neg); ATF_TP_ADD_TC(tp, scalbn_inf_pos); @@ -430,6 +537,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, scalbn_zero_neg); ATF_TP_ADD_TC(tp, scalbn_zero_pos); + ATF_TP_ADD_TC(tp, scalbnf_val); ATF_TP_ADD_TC(tp, scalbnf_nan); ATF_TP_ADD_TC(tp, scalbnf_inf_neg); ATF_TP_ADD_TC(tp, scalbnf_inf_pos); @@ -437,6 +545,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, scalbnf_zero_neg); ATF_TP_ADD_TC(tp, scalbnf_zero_pos); + ATF_TP_ADD_TC(tp, scalbnl_val); ATF_TP_ADD_TC(tp, scalbnl_nan); ATF_TP_ADD_TC(tp, scalbnl_inf_neg); ATF_TP_ADD_TC(tp, scalbnl_inf_pos);