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);