Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/tests/lib/libm Some of the acos() tests seem to fail on some...



details:   https://anonhg.NetBSD.org/src/rev/e13b8906b48a
branches:  trunk
changeset: 327205:e13b8906b48a
user:      dsl <dsl%NetBSD.org@localhost>
date:      Sat Mar 01 21:08:39 2014 +0000

description:
Some of the acos() tests seem to fail on some systems.
Sorting out why isn't helped by the tests not reporting the erronous value.
Change the 'boilerplate' pattern used so that all the values are output.
Reduce the amount of faffy red tape as well.
Some of these reductions could be shared with other libm tests, but for
  the moment they are defined in this file.
All these tests pass on my amd64 system, and when I run amd64 qemu.

diffstat:

 tests/lib/libm/t_acos.c |  288 ++++++++++++-----------------------------------
 1 files changed, 74 insertions(+), 214 deletions(-)

diffs (truncated from 335 to 300 lines):

diff -r 0e1e0ec6291f -r e13b8906b48a tests/lib/libm/t_acos.c
--- a/tests/lib/libm/t_acos.c   Sat Mar 01 21:03:01 2014 +0000
+++ b/tests/lib/libm/t_acos.c   Sat Mar 01 21:08:39 2014 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: t_acos.c,v 1.4 2013/04/09 12:11:04 isaki Exp $ */
+/* $NetBSD: t_acos.c,v 1.5 2014/03/01 21:08:39 dsl Exp $ */
 
 /*-
  * Copyright (c) 2011 The NetBSD Foundation, Inc.
@@ -32,78 +32,90 @@
 #include <atf-c.h>
 #include <math.h>
 
-static const struct {
-       double x;
-       double y;
-} values[] = {
-       { -1,    M_PI,              },
-       { -0.99, 3.000053180265366, },
-       { -0.5,  2.094395102393195, },
-       { -0.1,  1.670963747956456, },
-       {  0,    M_PI / 2,          },
-       {  0.1,  1.470628905633337, },
-       {  0.5,  1.047197551196598, },
-       {  0.99, 0.141539473324427, },
-};
+/*
+ * Check result of fn(arg) is correct within the bounds.
+ * Should be ok to do the checks using 'double' for 'float' functions.
+ */
+#define T_LIBM_CHECK(fn, arg, expect, epsilon) do { \
+       double r = fn(arg); \
+       double e = fabs(r - expect); \
+       if (e > epsilon) \
+               atf_tc_fail_nonfatal(#fn "(%g) is %g not %g (error %g > %g)", \
+                       arg, r, expect, e, epsilon); \
+    } while (0)
+
+/* Check that the result of fn(arg) is NaN */
+#ifndef __vax__
+#define T_LIBM_CHECK_NAN(fn, arg) do { \
+       double r = fn(arg); \
+       if (!isnan(r)) \
+               atf_tc_fail_nonfatal(#fn "(%g) is %g not NaN", arg, r); \
+    } while (0)
+#else
+/* vax doesn't support NaN */
+#define T_LIBM_CHECK_NAN(fn, arg) (void)(arg)
+#endif
+
+#define AFT_LIBM_TEST(name, description) \
+ATF_TC(name); \
+ATF_TC_HEAD(name, tc) { atf_tc_set_md_var(tc, "descr", description); } \
+ATF_TC_BODY(name, tc)
 
 /*
- * acos(3)
+ * acos(3) and acosf(3)
  */
-ATF_TC(acos_nan);
-ATF_TC_HEAD(acos_nan, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acos(NaN) == NaN");
-}
 
-ATF_TC_BODY(acos_nan, tc)
+AFT_LIBM_TEST(acos_nan, "Test acos/acosf(x) == NaN, x = NaN, +/-Inf, ![-1..1]")
 {
-#ifndef __vax__
-       const double x = 0.0L / 0.0L;
+       static const double x[] = {
+           -1.000000001, 1.000000001,
+           -1.0000001, 1.0000001,
+           -1.1, 1.1,
+           0.0L / 0.0L,  /* NAN */
+           -1.0L / 0.0L, /* -Inf */
+           +1.0L / 0.0L, /* +Inf */
+       };
+       size_t i;
 
-       if (isnan(acos(x)) == 0)
-               atf_tc_fail_nonfatal("acos(NaN) != NaN");
-#endif
+       for (i = 0; i < __arraycount(x); i++) {
+               T_LIBM_CHECK_NAN(acos, x[i]);
+               if (i < 2)
+                       /* Values are too small for float */
+                       continue;
+               T_LIBM_CHECK_NAN(acosf, x[i]);
+       }
 }
 
-ATF_TC(acos_inf_neg);
-ATF_TC_HEAD(acos_inf_neg, tc)
+AFT_LIBM_TEST(acos_inrange, "Test acos/acosf(x) for some valid values")
 {
-       atf_tc_set_md_var(tc, "descr", "Test acos(-Inf) == NaN");
-}
+       static const struct {
+               double x;
+               double y;
+       } values[] = {
+               { -1,    M_PI,              },
+               { -0.99, 3.000053180265366, },
+               { -0.5,  2.094395102393195, },
+               { -0.1,  1.670963747956456, },
+               {  0,    M_PI / 2,          },
+               {  0.1,  1.470628905633337, },
+               {  0.5,  1.047197551196598, },
+               {  0.99, 0.141539473324427, },
+       };
+       size_t i;
 
-ATF_TC_BODY(acos_inf_neg, tc)
-{
-#ifndef __vax__
-       const double x = -1.0L / 0.0L;
+       /*
+        * Note that acos(x) might be calcualted as atan((1-x*x)/x).
+        * This means that acos(-1) is atan(-0.0), if the sign is lost
+        * the value will be 0 (atan(+0)) not M_PI.
+        */
 
-       if (isnan(acos(x)) == 0)
-               atf_tc_fail_nonfatal("acos(-Inf) != NaN");
-#endif
+       for (i = 0; i < __arraycount(values); i++) {
+               T_LIBM_CHECK(acos, values[i].x, values[i].y, 1.0e-15);
+               T_LIBM_CHECK(acosf, values[i].x, values[i].y, 1.0e-5);
+       }
 }
 
-ATF_TC(acos_inf_pos);
-ATF_TC_HEAD(acos_inf_pos, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acos(+Inf) == NaN");
-}
-
-ATF_TC_BODY(acos_inf_pos, tc)
-{
-#ifndef __vax__
-       const double x = 1.0L / 0.0L;
-
-       if (isnan(acos(x)) == 0)
-               atf_tc_fail_nonfatal("acos(+Inf) != NaN");
-#endif
-}
-
-ATF_TC(acos_one_pos);
-ATF_TC_HEAD(acos_one_pos, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acos(1.0) == +0.0");
-}
-
-ATF_TC_BODY(acos_one_pos, tc)
+AFT_LIBM_TEST(acos_one_pos, "Test acos(1.0) == +0.0")
 {
 #ifndef __vax__
        const double y = acos(1.0);
@@ -113,107 +125,7 @@
 #endif
 }
 
-ATF_TC(acos_range);
-ATF_TC_HEAD(acos_range, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acos(x) == NaN, x < -1, x > 1");
-}
-
-ATF_TC_BODY(acos_range, tc)
-{
-#ifndef __vax__
-       const double x[] = { -1.1, -1.000000001, 1.1, 1.000000001 };
-       size_t i;
-
-       for (i = 0; i < __arraycount(x); i++) {
-
-               if (isnan(acos(x[i])) == 0)
-                       atf_tc_fail_nonfatal("acos(%f) != NaN", x[i]);
-       }
-#endif
-}
-
-ATF_TC(acos_inrange);
-ATF_TC_HEAD(acos_inrange, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acos(x) for some values");
-}
-
-ATF_TC_BODY(acos_inrange, tc)
-{
-#ifndef __vax__
-       const double eps = 1.0e-15;
-       double x;
-       double y;
-       size_t i;
-
-       for (i = 0; i < __arraycount(values); i++) {
-               x = values[i].x;
-               y = values[i].y;
-               if (fabs(acos(x) - y) > eps)
-                       atf_tc_fail_nonfatal("acos(%g) != %g", x, y);
-       }
-#endif
-}
-
-/*
- * acosf(3)
- */
-ATF_TC(acosf_nan);
-ATF_TC_HEAD(acosf_nan, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acosf(NaN) == NaN");
-}
-
-ATF_TC_BODY(acosf_nan, tc)
-{
-#ifndef __vax__
-       const float x = 0.0L / 0.0L;
-
-       if (isnan(acosf(x)) == 0)
-               atf_tc_fail_nonfatal("acosf(NaN) != NaN");
-#endif
-}
-
-ATF_TC(acosf_inf_neg);
-ATF_TC_HEAD(acosf_inf_neg, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acosf(-Inf) == NaN");
-}
-
-ATF_TC_BODY(acosf_inf_neg, tc)
-{
-#ifndef __vax__
-       const float x = -1.0L / 0.0L;
-
-       if (isnan(acosf(x)) == 0)
-               atf_tc_fail_nonfatal("acosf(-Inf) != NaN");
-#endif
-}
-
-ATF_TC(acosf_inf_pos);
-ATF_TC_HEAD(acosf_inf_pos, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acosf(+Inf) == NaN");
-}
-
-ATF_TC_BODY(acosf_inf_pos, tc)
-{
-#ifndef __vax__
-       const float x = 1.0L / 0.0L;
-
-       if (isnan(acosf(x)) == 0)
-               atf_tc_fail_nonfatal("acosf(+Inf) != NaN");
-#endif
-}
-
-ATF_TC(acosf_one_pos);
-ATF_TC_HEAD(acosf_one_pos, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acosf(1.0) == +0.0");
-}
-
-ATF_TC_BODY(acosf_one_pos, tc)
+AFT_LIBM_TEST(acosf_one_pos, "Test acosf(1.0) == +0.0")
 {
 #ifndef __vax__
        const float y = acosf(1.0);
@@ -223,65 +135,13 @@
 #endif
 }
 
-ATF_TC(acosf_range);
-ATF_TC_HEAD(acosf_range, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acosf(x) == NaN, x < -1, x > 1");
-}
-
-ATF_TC_BODY(acosf_range, tc)
-{
-#ifndef __vax__
-       const float x[] = { -1.1, -1.0000001, 1.1, 1.0000001 };
-       size_t i;
-
-       for (i = 0; i < __arraycount(x); i++) {
-
-               if (isnan(acosf(x[i])) == 0)
-                       atf_tc_fail_nonfatal("acosf(%f) != NaN", x[i]);
-       }
-#endif
-}
-
-ATF_TC(acosf_inrange);
-ATF_TC_HEAD(acosf_inrange, tc)
-{
-       atf_tc_set_md_var(tc, "descr", "Test acosf(x) for some values");
-}
-
-ATF_TC_BODY(acosf_inrange, tc)
-{



Home | Main Index | Thread Index | Old Index