aboutsummaryrefslogtreecommitdiff
path: root/lib/libm
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libm')
-rw-r--r--lib/libm/Makefile44
-rw-r--r--lib/libm/t_acos.c105
-rw-r--r--lib/libm/t_asin.c296
-rw-r--r--lib/libm/t_atan.c101
-rw-r--r--lib/libm/t_cbrt.c366
-rw-r--r--lib/libm/t_ceil.c931
-rw-r--r--lib/libm/t_cos.c263
-rw-r--r--lib/libm/t_cosh.c270
-rw-r--r--lib/libm/t_erf.c299
-rw-r--r--lib/libm/t_exp.c567
-rw-r--r--lib/libm/t_fmod.c63
-rw-r--r--lib/libm/t_infinity.c119
-rw-r--r--lib/libm/t_ldexp.c481
-rw-r--r--lib/libm/t_libm.h62
-rw-r--r--lib/libm/t_log.c885
-rw-r--r--lib/libm/t_modf.c68
-rw-r--r--lib/libm/t_pow.c669
-rw-r--r--lib/libm/t_precision.c76
-rw-r--r--lib/libm/t_round.c85
-rw-r--r--lib/libm/t_scalbn.c523
-rw-r--r--lib/libm/t_sin.c263
-rw-r--r--lib/libm/t_sinh.c273
-rw-r--r--lib/libm/t_sqrt.c368
-rw-r--r--lib/libm/t_tan.c260
-rw-r--r--lib/libm/t_tanh.c207
25 files changed, 7644 insertions, 0 deletions
diff --git a/lib/libm/Makefile b/lib/libm/Makefile
new file mode 100644
index 000000000000..d45cb90cbe83
--- /dev/null
+++ b/lib/libm/Makefile
@@ -0,0 +1,44 @@
+# $NetBSD: Makefile,v 1.26 2014/08/10 11:30:51 martin Exp $
+
+.include <bsd.own.mk>
+
+TESTSDIR= ${TESTSBASE}/lib/libm
+
+.if ${MACHINE_CPU} == "aarch64" || ${MACHINE_CPU} == "arm" \
+ || ${MACHINE_ARCH} == "sparc" || ${MACHINE_ARCH} == "sparc64" \
+ || ${MACHINE_ARCH} == "i386" || ${MACHINE_ARCH} == "x86_64"
+CPPFLAGS+= -DHAVE_FENV_H
+.endif
+
+.if ${MACHINE} == "alpha"
+COPTS+= -mfloat-ieee -mieee-with-inexact -mfp-trap-mode=sui -mtrap-precision=i
+.endif
+
+TESTS_C+= t_acos
+TESTS_C+= t_asin
+TESTS_C+= t_atan
+TESTS_C+= t_cbrt
+TESTS_C+= t_ceil
+TESTS_C+= t_cos
+TESTS_C+= t_cosh
+TESTS_C+= t_erf
+TESTS_C+= t_exp
+TESTS_C+= t_fmod
+TESTS_C+= t_infinity
+TESTS_C+= t_ldexp
+TESTS_C+= t_log
+TESTS_C+= t_modf
+TESTS_C+= t_pow
+TESTS_C+= t_precision
+TESTS_C+= t_round
+TESTS_C+= t_scalbn
+TESTS_C+= t_sin
+TESTS_C+= t_sinh
+TESTS_C+= t_sqrt
+TESTS_C+= t_tan
+TESTS_C+= t_tanh
+
+LDADD+= -lm
+#COPTS+= -Wfloat-equal
+
+.include <bsd.test.mk>
diff --git a/lib/libm/t_acos.c b/lib/libm/t_acos.c
new file mode 100644
index 000000000000..f051fb64df42
--- /dev/null
+++ b/lib/libm/t_acos.c
@@ -0,0 +1,105 @@
+/* $NetBSD: t_acos.c,v 1.10 2014/03/05 20:14:46 dsl Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+#include "t_libm.h"
+
+/*
+ * acos(3) and acosf(3)
+ */
+
+ATF_LIBM_TEST(acos_is_nan, "Test acos/acosf(x) == NaN, x = NaN, +/-Inf, ![-1..1]")
+{
+ static const double x[] = {
+ -1.000000001, 1.000000001,
+ -1.0000001, 1.0000001,
+ -1.1, 1.1,
+#ifndef __vax__
+ T_LIBM_NAN,
+ T_LIBM_MINUS_INF, T_LIBM_PLUS_INF,
+#endif
+ };
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+ T_LIBM_CHECK_NAN(i, acos, x[i]);
+ if (i < 2)
+ /* Values are too small for float */
+ continue;
+ T_LIBM_CHECK_NAN(i, acosf, x[i]);
+ }
+}
+
+ATF_LIBM_TEST(acos_inrange, "Test acos/acosf(x) for some valid values")
+{
+ 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, },
+ };
+ unsigned int i;
+
+ /*
+ * Note that acos(x) might be calculated as atan2(sqrt(1-x*x),x).
+ * This means that acos(-1) is atan2(+0,-1), if the sign is wrong
+ * the value will be -M_PI (atan2(-0,-1)) not M_PI.
+ */
+
+ for (i = 0; i < __arraycount(values); i++) {
+ T_LIBM_CHECK(i, acos, values[i].x, values[i].y, 1.0e-15);
+ T_LIBM_CHECK(i, acosf, values[i].x, values[i].y, 1.0e-5);
+ }
+}
+
+ATF_LIBM_TEST(acos_is_plus_zero, "Test acosf(1.0) == +0.0")
+{
+ T_LIBM_CHECK_PLUS_ZERO(0, acos, 1.0);
+ T_LIBM_CHECK_PLUS_ZERO(0, acosf, 1.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, acos_inrange);
+ ATF_TP_ADD_TC(tp, acos_is_nan);
+ ATF_TP_ADD_TC(tp, acos_is_plus_zero);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_asin.c b/lib/libm/t_asin.c
new file mode 100644
index 000000000000..06de85216429
--- /dev/null
+++ b/lib/libm/t_asin.c
@@ -0,0 +1,296 @@
+/* $NetBSD: t_asin.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+
+static const struct {
+ double x;
+ double y;
+} values[] = {
+ { -1.0, -M_PI / 2, },
+ { -0.9, -1.119769514998634, },
+ { -0.5, -M_PI / 6, },
+ { -0.1, -0.1001674211615598, },
+ { 0.1, 0.1001674211615598, },
+ { 0.5, M_PI / 6, },
+ { 0.9, 1.119769514998634, },
+ { 1.0, M_PI / 2, },
+};
+
+/*
+ * asin(3)
+ */
+ATF_TC(asin_nan);
+ATF_TC_HEAD(asin_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(NaN) == NaN");
+}
+
+ATF_TC_BODY(asin_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ if (isnan(asin(x)) == 0)
+ atf_tc_fail_nonfatal("asin(NaN) != NaN");
+}
+
+ATF_TC(asin_inf_neg);
+ATF_TC_HEAD(asin_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(-Inf) == NaN");
+}
+
+ATF_TC_BODY(asin_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (isnan(asin(x)) == 0)
+ atf_tc_fail_nonfatal("asin(-Inf) != NaN");
+}
+
+ATF_TC(asin_inf_pos);
+ATF_TC_HEAD(asin_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(+Inf) == NaN");
+}
+
+ATF_TC_BODY(asin_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ if (isnan(asin(x)) == 0)
+ atf_tc_fail_nonfatal("asin(+Inf) != NaN");
+}
+
+ATF_TC(asin_range);
+ATF_TC_HEAD(asin_range, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(x) == NaN, x < -1, x > 1");
+}
+
+ATF_TC_BODY(asin_range, tc)
+{
+ const double x[] = { -1.1, -1.000000001, 1.1, 1.000000001 };
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (isnan(asin(x[i])) == 0)
+ atf_tc_fail_nonfatal("asin(%f) != NaN", x[i]);
+ }
+}
+
+ATF_TC(asin_inrange);
+ATF_TC_HEAD(asin_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(x) for some values");
+}
+
+ATF_TC_BODY(asin_inrange, tc)
+{
+ const double eps = 1.0e-15;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ y = asin(values[i].x);
+ if (fabs(y - values[i].y) > eps)
+ atf_tc_fail_nonfatal("asin(%g) != %g",
+ values[i].x, values[i].y);
+ }
+}
+
+ATF_TC(asin_zero_neg);
+ATF_TC_HEAD(asin_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(asin_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = asin(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("asin(-0.0) != -0.0");
+}
+
+ATF_TC(asin_zero_pos);
+ATF_TC_HEAD(asin_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asin(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(asin_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = asin(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("asin(+0.0) != +0.0");
+}
+
+/*
+ * asinf(3)
+ */
+ATF_TC(asinf_nan);
+ATF_TC_HEAD(asinf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(NaN) == NaN");
+}
+
+ATF_TC_BODY(asinf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ if (isnan(asinf(x)) == 0)
+ atf_tc_fail_nonfatal("asinf(NaN) != NaN");
+}
+
+ATF_TC(asinf_inf_neg);
+ATF_TC_HEAD(asinf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(asinf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(asinf(x)) == 0)
+ atf_tc_fail_nonfatal("asinf(-Inf) != NaN");
+}
+
+ATF_TC(asinf_inf_pos);
+ATF_TC_HEAD(asinf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(asinf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(asinf(x)) == 0)
+ atf_tc_fail_nonfatal("asinf(+Inf) != NaN");
+}
+
+ATF_TC(asinf_range);
+ATF_TC_HEAD(asinf_range, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(x) == NaN, x < -1, x > 1");
+}
+
+ATF_TC_BODY(asinf_range, tc)
+{
+ const float x[] = { -1.1, -1.0000001, 1.1, 1.0000001 };
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (isnan(asinf(x[i])) == 0)
+ atf_tc_fail_nonfatal("asinf(%f) != NaN", x[i]);
+ }
+}
+
+ATF_TC(asinf_inrange);
+ATF_TC_HEAD(asinf_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(x) for some values");
+}
+
+ATF_TC_BODY(asinf_inrange, tc)
+{
+ const float eps = 1.0e-6;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ if (fabs(asinf(x) - y) > eps)
+ atf_tc_fail_nonfatal("asinf(%g) != %g", x, y);
+ }
+}
+
+ATF_TC(asinf_zero_neg);
+ATF_TC_HEAD(asinf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(asinf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = asinf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("asinf(-0.0) != -0.0");
+}
+
+ATF_TC(asinf_zero_pos);
+ATF_TC_HEAD(asinf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test asinf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(asinf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = asinf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("asinf(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, asin_nan);
+ ATF_TP_ADD_TC(tp, asin_inf_neg);
+ ATF_TP_ADD_TC(tp, asin_inf_pos);
+ ATF_TP_ADD_TC(tp, asin_range);
+ ATF_TP_ADD_TC(tp, asin_inrange);
+ ATF_TP_ADD_TC(tp, asin_zero_neg);
+ ATF_TP_ADD_TC(tp, asin_zero_pos);
+
+ ATF_TP_ADD_TC(tp, asinf_nan);
+ ATF_TP_ADD_TC(tp, asinf_inf_neg);
+ ATF_TP_ADD_TC(tp, asinf_inf_pos);
+ ATF_TP_ADD_TC(tp, asinf_range);
+ ATF_TP_ADD_TC(tp, asinf_inrange);
+ ATF_TP_ADD_TC(tp, asinf_zero_neg);
+ ATF_TP_ADD_TC(tp, asinf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_atan.c b/lib/libm/t_atan.c
new file mode 100644
index 000000000000..c3aa15f773c1
--- /dev/null
+++ b/lib/libm/t_atan.c
@@ -0,0 +1,101 @@
+/* $NetBSD: t_atan.c,v 1.15 2014/03/17 11:08:11 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+#include "t_libm.h"
+
+static const struct {
+ double x;
+ double y;
+} values[] = {
+#ifndef __vax__
+ /* vax has no +/- INF */
+ { T_LIBM_MINUS_INF, -M_PI / 2 },
+ { T_LIBM_PLUS_INF, M_PI / 2 },
+#endif
+ { -100, -1.560796660108231, },
+ { -10, -1.471127674303735, },
+ { -1, -M_PI / 4, },
+ { -0.1, -0.09966865249116204, },
+ { 0.1, 0.09966865249116204, },
+ { 1, M_PI / 4, },
+ { 10, 1.471127674303735, },
+ { 100, 1.560796660108231, },
+};
+
+/*
+ * atan(3)
+ */
+ATF_LIBM_TEST(atan_nan, "Test atan/atanf(NaN) == NaN")
+{
+#ifdef T_LIBM_NAN
+ T_LIBM_CHECK_NAN(0, atan, T_LIBM_NAN);
+ T_LIBM_CHECK_NAN(0, atanf, T_LIBM_NAN);
+#else
+ atf_tc_skip("no NaN on this machine");
+#endif
+}
+
+ATF_LIBM_TEST(atan_inrange, "Test atan/atanf(x) for some values")
+{
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ T_LIBM_CHECK(i, atan, values[i].x, values[i].y, 1.0e-15);
+ T_LIBM_CHECK(i, atanf, values[i].x, values[i].y, 1.0e-7);
+ }
+}
+
+ATF_LIBM_TEST(atan_zero_neg, "Test atan/atanf(-0.0) == -0.0")
+{
+
+ T_LIBM_CHECK_MINUS_ZERO(0, atan, -0.0);
+ T_LIBM_CHECK_MINUS_ZERO(0, atanf, -0.0);
+}
+
+ATF_LIBM_TEST(atan_zero_pos, "Test atan/atanf(+0.0) == +0.0")
+{
+
+ T_LIBM_CHECK_PLUS_ZERO(0, atan, +0.0);
+ T_LIBM_CHECK_PLUS_ZERO(0, atanf, +0.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, atan_nan);
+ ATF_TP_ADD_TC(tp, atan_inrange);
+ ATF_TP_ADD_TC(tp, atan_zero_neg);
+ ATF_TP_ADD_TC(tp, atan_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_cbrt.c b/lib/libm/t_cbrt.c
new file mode 100644
index 000000000000..a7de9f629815
--- /dev/null
+++ b/lib/libm/t_cbrt.c
@@ -0,0 +1,366 @@
+/* $NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+
+/*
+ * cbrt(3)
+ */
+ATF_TC(cbrt_nan);
+ATF_TC_HEAD(cbrt_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(NaN) == NaN");
+}
+
+ATF_TC_BODY(cbrt_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cbrt(x)) != 0);
+}
+
+ATF_TC(cbrt_pow);
+ATF_TC_HEAD(cbrt_pow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(3) vs. pow(3)");
+}
+
+ATF_TC_BODY(cbrt_pow, tc)
+{
+ const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 };
+ const double eps = 1.0e-14;
+ double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = cbrt(x[i]);
+ z = pow(x[i], 1.0 / 3.0);
+
+ if (fabs(y - z) > eps)
+ atf_tc_fail_nonfatal("cbrt(%0.03f) != "
+ "pow(%0.03f, 1/3)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(cbrt_inf_neg);
+ATF_TC_HEAD(cbrt_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(cbrt_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = cbrt(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(cbrt_inf_pos);
+ATF_TC_HEAD(cbrt_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cbrt_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = cbrt(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cbrt_zero_neg);
+ATF_TC_HEAD(cbrt_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(cbrt_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = cbrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("cbrt(-0.0) != -0.0");
+}
+
+ATF_TC(cbrt_zero_pos);
+ATF_TC_HEAD(cbrt_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrt(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(cbrt_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = cbrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("cbrt(+0.0) != +0.0");
+}
+
+/*
+ * cbrtf(3)
+ */
+ATF_TC(cbrtf_nan);
+ATF_TC_HEAD(cbrtf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(NaN) == NaN");
+}
+
+ATF_TC_BODY(cbrtf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cbrtf(x)) != 0);
+}
+
+ATF_TC(cbrtf_powf);
+ATF_TC_HEAD(cbrtf_powf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(3) vs. powf(3)");
+}
+
+ATF_TC_BODY(cbrtf_powf, tc)
+{
+ const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 };
+ const float eps = 1.0e-5;
+ float y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = cbrtf(x[i]);
+ z = powf(x[i], 1.0 / 3.0);
+
+ if (fabsf(y - z) > eps)
+ atf_tc_fail_nonfatal("cbrtf(%0.03f) != "
+ "powf(%0.03f, 1/3)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(cbrtf_inf_neg);
+ATF_TC_HEAD(cbrtf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(cbrtf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = cbrtf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(cbrtf_inf_pos);
+ATF_TC_HEAD(cbrtf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cbrtf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = cbrtf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cbrtf_zero_neg);
+ATF_TC_HEAD(cbrtf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(cbrtf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = cbrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("cbrtf(-0.0) != -0.0");
+}
+
+ATF_TC(cbrtf_zero_pos);
+ATF_TC_HEAD(cbrtf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(cbrtf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = cbrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("cbrtf(+0.0) != +0.0");
+}
+
+/*
+ * cbrtl(3)
+ */
+ATF_TC(cbrtl_nan);
+ATF_TC_HEAD(cbrtl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(NaN) == NaN");
+}
+
+ATF_TC_BODY(cbrtl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cbrtl(x)) != 0);
+}
+
+ATF_TC(cbrtl_powl);
+ATF_TC_HEAD(cbrtl_powl, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(3) vs. powl(3)");
+}
+
+ATF_TC_BODY(cbrtl_powl, tc)
+{
+ const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.0 };
+ const long double eps = 1.0e-15;
+ long double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = cbrtl(x[i]);
+ z = powl(x[i], 1.0 / 3.0);
+
+ if (fabsl(y - z) > eps * fabsl(1 + x[i]))
+ atf_tc_fail_nonfatal("cbrtl(%0.03Lf) != "
+ "powl(%0.03Lf, 1/3)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(cbrtl_inf_neg);
+ATF_TC_HEAD(cbrtl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(cbrtl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = cbrtl(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(cbrtl_inf_pos);
+ATF_TC_HEAD(cbrtl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cbrtl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = cbrtl(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cbrtl_zero_neg);
+ATF_TC_HEAD(cbrtl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(cbrtl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = cbrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("cbrtl(-0.0) != -0.0");
+}
+
+ATF_TC(cbrtl_zero_pos);
+ATF_TC_HEAD(cbrtl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cbrtl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(cbrtl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = cbrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("cbrtl(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cbrt_nan);
+ ATF_TP_ADD_TC(tp, cbrt_pow);
+ ATF_TP_ADD_TC(tp, cbrt_inf_neg);
+ ATF_TP_ADD_TC(tp, cbrt_inf_pos);
+ ATF_TP_ADD_TC(tp, cbrt_zero_neg);
+ ATF_TP_ADD_TC(tp, cbrt_zero_pos);
+
+ ATF_TP_ADD_TC(tp, cbrtf_nan);
+ ATF_TP_ADD_TC(tp, cbrtf_powf);
+ ATF_TP_ADD_TC(tp, cbrtf_inf_neg);
+ ATF_TP_ADD_TC(tp, cbrtf_inf_pos);
+ ATF_TP_ADD_TC(tp, cbrtf_zero_neg);
+ ATF_TP_ADD_TC(tp, cbrtf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, cbrtl_nan);
+ ATF_TP_ADD_TC(tp, cbrtl_powl);
+ ATF_TP_ADD_TC(tp, cbrtl_inf_neg);
+ ATF_TP_ADD_TC(tp, cbrtl_inf_pos);
+ ATF_TP_ADD_TC(tp, cbrtl_zero_neg);
+ ATF_TP_ADD_TC(tp, cbrtl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_ceil.c b/lib/libm/t_ceil.c
new file mode 100644
index 000000000000..b57f30ebf8b2
--- /dev/null
+++ b/lib/libm/t_ceil.c
@@ -0,0 +1,931 @@
+/* $NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_ceil.c,v 1.10 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <limits.h>
+#include <stdio.h>
+
+#ifdef __vax__
+#define SMALL_NUM 1.0e-38
+#else
+#define SMALL_NUM 1.0e-40
+#endif
+
+/*
+ * ceil(3)
+ */
+ATF_TC(ceil_basic);
+ATF_TC_HEAD(ceil_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ceil(3)");
+}
+
+ATF_TC_BODY(ceil_basic, tc)
+{
+ const double x = 0.999999999999999;
+ const double y = 0.000000000000001;
+
+ ATF_CHECK(fabs(ceil(x) - 1) < SMALL_NUM);
+ ATF_CHECK(fabs(ceil(y) - 1) < SMALL_NUM);
+}
+
+ATF_TC(ceil_nan);
+ATF_TC_HEAD(ceil_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(NaN) == NaN");
+}
+
+ATF_TC_BODY(ceil_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(ceil(x)) != 0);
+}
+
+ATF_TC(ceil_inf_neg);
+ATF_TC_HEAD(ceil_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ceil_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = ceil(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceil(-Inf) != -Inf");
+}
+
+ATF_TC(ceil_inf_pos);
+ATF_TC_HEAD(ceil_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ceil_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = ceil(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceil(+Inf) != +Inf");
+}
+
+ATF_TC(ceil_zero_neg);
+ATF_TC_HEAD(ceil_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ceil_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = ceil(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceil(-0.0) != -0.0");
+}
+
+ATF_TC(ceil_zero_pos);
+ATF_TC_HEAD(ceil_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceil(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ceil_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = ceil(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceil(+0.0) != +0.0");
+}
+
+/*
+ * ceilf(3)
+ */
+ATF_TC(ceilf_basic);
+ATF_TC_HEAD(ceilf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ceilf(3)");
+}
+
+ATF_TC_BODY(ceilf_basic, tc)
+{
+ const float x = 0.9999999;
+ const float y = 0.0000001;
+
+ ATF_CHECK(fabsf(ceilf(x) - 1) < SMALL_NUM);
+ ATF_CHECK(fabsf(ceilf(y) - 1) < SMALL_NUM);
+}
+
+ATF_TC(ceilf_nan);
+ATF_TC_HEAD(ceilf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(NaN) == NaN");
+}
+
+ATF_TC_BODY(ceilf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(ceilf(x)) != 0);
+}
+
+ATF_TC(ceilf_inf_neg);
+ATF_TC_HEAD(ceilf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ceilf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = ceilf(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceilf(-Inf) != -Inf");
+}
+
+ATF_TC(ceilf_inf_pos);
+ATF_TC_HEAD(ceilf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ceilf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = ceilf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceilf(+Inf) != +Inf");
+}
+
+ATF_TC(ceilf_zero_neg);
+ATF_TC_HEAD(ceilf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ceilf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = ceilf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceilf(-0.0) != -0.0");
+}
+
+ATF_TC(ceilf_zero_pos);
+ATF_TC_HEAD(ceilf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceilf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ceilf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = ceilf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceilf(+0.0) != +0.0");
+}
+
+/*
+ * ceill(3)
+ */
+ATF_TC(ceill_basic);
+ATF_TC_HEAD(ceill_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of ceill(3)");
+}
+
+ATF_TC_BODY(ceill_basic, tc)
+{
+ const long double x = 0.9999999;
+ const long double y = 0.0000001;
+
+ ATF_CHECK(fabsl(ceill(x) - 1) < SMALL_NUM);
+ ATF_CHECK(fabsl(ceill(y) - 1) < SMALL_NUM);
+}
+
+ATF_TC(ceill_nan);
+ATF_TC_HEAD(ceill_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(NaN) == NaN");
+}
+
+ATF_TC_BODY(ceill_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(ceill(x)) != 0);
+}
+
+ATF_TC(ceill_inf_neg);
+ATF_TC_HEAD(ceill_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ceill_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = ceill(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceill(-Inf) != -Inf");
+}
+
+ATF_TC(ceill_inf_pos);
+ATF_TC_HEAD(ceill_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ceill_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = ceill(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceill(+Inf) != +Inf");
+}
+
+ATF_TC(ceill_zero_neg);
+ATF_TC_HEAD(ceill_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ceill_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = ceill(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("ceill(-0.0) != -0.0");
+}
+
+ATF_TC(ceill_zero_pos);
+ATF_TC_HEAD(ceill_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ceill(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ceill_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = ceill(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("ceill(+0.0) != +0.0");
+}
+
+/*
+ * floor(3)
+ */
+ATF_TC(floor_basic);
+ATF_TC_HEAD(floor_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of floor(3)");
+}
+
+ATF_TC_BODY(floor_basic, tc)
+{
+ const double x = 0.999999999999999;
+ const double y = 0.000000000000001;
+
+ ATF_CHECK(floor(x) < SMALL_NUM);
+ ATF_CHECK(floor(y) < SMALL_NUM);
+}
+
+ATF_TC(floor_nan);
+ATF_TC_HEAD(floor_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(NaN) == NaN");
+}
+
+ATF_TC_BODY(floor_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(floor(x)) != 0);
+}
+
+ATF_TC(floor_inf_neg);
+ATF_TC_HEAD(floor_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(floor_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = floor(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floor(-Inf) != -Inf");
+}
+
+ATF_TC(floor_inf_pos);
+ATF_TC_HEAD(floor_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(floor_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = floor(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floor(+Inf) != +Inf");
+}
+
+ATF_TC(floor_zero_neg);
+ATF_TC_HEAD(floor_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(floor_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = floor(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floor(-0.0) != -0.0");
+}
+
+ATF_TC(floor_zero_pos);
+ATF_TC_HEAD(floor_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floor(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(floor_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = floor(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floor(+0.0) != +0.0");
+}
+
+/*
+ * floorf(3)
+ */
+ATF_TC(floorf_basic);
+ATF_TC_HEAD(floorf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of floorf(3)");
+}
+
+ATF_TC_BODY(floorf_basic, tc)
+{
+ const float x = 0.9999999;
+ const float y = 0.0000001;
+
+ ATF_CHECK(floorf(x) < SMALL_NUM);
+ ATF_CHECK(floorf(y) < SMALL_NUM);
+}
+
+ATF_TC(floorf_nan);
+ATF_TC_HEAD(floorf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(NaN) == NaN");
+}
+
+ATF_TC_BODY(floorf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(floorf(x)) != 0);
+}
+
+ATF_TC(floorf_inf_neg);
+ATF_TC_HEAD(floorf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(floorf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = floorf(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorf(-Inf) != -Inf");
+}
+
+ATF_TC(floorf_inf_pos);
+ATF_TC_HEAD(floorf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(floorf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = floorf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorf(+Inf) != +Inf");
+}
+
+ATF_TC(floorf_zero_neg);
+ATF_TC_HEAD(floorf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(floorf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = floorf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorf(-0.0) != -0.0");
+}
+
+ATF_TC(floorf_zero_pos);
+ATF_TC_HEAD(floorf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(floorf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = floorf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorf(+0.0) != +0.0");
+}
+
+/*
+ * floorl(3)
+ */
+ATF_TC(floorl_basic);
+ATF_TC_HEAD(floorl_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of floorl(3)");
+}
+
+ATF_TC_BODY(floorl_basic, tc)
+{
+ const long double x = 0.9999999;
+ const long double y = 0.0000001;
+
+ ATF_CHECK(floorl(x) < SMALL_NUM);
+ ATF_CHECK(floorl(y) < SMALL_NUM);
+}
+
+ATF_TC(floorl_nan);
+ATF_TC_HEAD(floorl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(NaN) == NaN");
+}
+
+ATF_TC_BODY(floorl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(floorl(x)) != 0);
+}
+
+ATF_TC(floorl_inf_neg);
+ATF_TC_HEAD(floorl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(floorl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = floorl(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorl(-Inf) != -Inf");
+}
+
+ATF_TC(floorl_inf_pos);
+ATF_TC_HEAD(floorl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(floorl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = floorl(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorl(+Inf) != +Inf");
+}
+
+ATF_TC(floorl_zero_neg);
+ATF_TC_HEAD(floorl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(floorl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = floorl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("floorl(-0.0) != -0.0");
+}
+
+ATF_TC(floorl_zero_pos);
+ATF_TC_HEAD(floorl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test floorl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(floorl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = floorl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("floorl(+0.0) != +0.0");
+}
+
+/*
+ * trunc(3)
+ */
+ATF_TC(trunc_basic);
+ATF_TC_HEAD(trunc_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of trunc(3)");
+}
+
+ATF_TC_BODY(trunc_basic, tc)
+{
+ const double x = 0.999999999999999;
+ const double y = 0.000000000000001;
+
+ ATF_CHECK(trunc(x) < SMALL_NUM);
+ ATF_CHECK(trunc(y) < SMALL_NUM);
+}
+
+ATF_TC(trunc_nan);
+ATF_TC_HEAD(trunc_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(NaN) == NaN");
+}
+
+ATF_TC_BODY(trunc_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(trunc(x)) != 0);
+}
+
+ATF_TC(trunc_inf_neg);
+ATF_TC_HEAD(trunc_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(trunc_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = trunc(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("trunc(-Inf) != -Inf");
+}
+
+ATF_TC(trunc_inf_pos);
+ATF_TC_HEAD(trunc_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(trunc_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = trunc(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("trunc(+Inf) != +Inf");
+}
+
+ATF_TC(trunc_zero_neg);
+ATF_TC_HEAD(trunc_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(trunc_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = trunc(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("trunc(-0.0) != -0.0");
+}
+
+ATF_TC(trunc_zero_pos);
+ATF_TC_HEAD(trunc_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test trunc(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(trunc_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = trunc(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("trunc(+0.0) != +0.0");
+}
+
+/*
+ * truncf(3)
+ */
+ATF_TC(truncf_basic);
+ATF_TC_HEAD(truncf_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of truncf(3)");
+}
+
+ATF_TC_BODY(truncf_basic, tc)
+{
+ const float x = 0.9999999;
+ const float y = 0.0000001;
+
+ ATF_CHECK(truncf(x) < SMALL_NUM);
+ ATF_CHECK(truncf(y) < SMALL_NUM);
+}
+
+ATF_TC(truncf_nan);
+ATF_TC_HEAD(truncf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(NaN) == NaN");
+}
+
+ATF_TC_BODY(truncf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(truncf(x)) != 0);
+}
+
+ATF_TC(truncf_inf_neg);
+ATF_TC_HEAD(truncf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(truncf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = truncf(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncf(-Inf) != -Inf");
+}
+
+ATF_TC(truncf_inf_pos);
+ATF_TC_HEAD(truncf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(truncf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = truncf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncf(+Inf) != +Inf");
+}
+
+ATF_TC(truncf_zero_neg);
+ATF_TC_HEAD(truncf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(truncf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = truncf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncf(-0.0) != -0.0");
+}
+
+ATF_TC(truncf_zero_pos);
+ATF_TC_HEAD(truncf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(truncf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = truncf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncf(+0.0) != +0.0");
+}
+
+/*
+ * truncl(3)
+ */
+ATF_TC(truncl_basic);
+ATF_TC_HEAD(truncl_basic, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "A basic test of truncl(3)");
+}
+
+ATF_TC_BODY(truncl_basic, tc)
+{
+ const long double x = 0.9999999;
+ const long double y = 0.0000001;
+
+ ATF_CHECK(truncl(x) < SMALL_NUM);
+ ATF_CHECK(truncl(y) < SMALL_NUM);
+}
+
+ATF_TC(truncl_nan);
+ATF_TC_HEAD(truncl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(NaN) == NaN");
+}
+
+ATF_TC_BODY(truncl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(truncl(x)) != 0);
+}
+
+ATF_TC(truncl_inf_neg);
+ATF_TC_HEAD(truncl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(truncl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = truncl(x);
+
+ if (isinf(y) == 0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncl(-Inf) != -Inf");
+}
+
+ATF_TC(truncl_inf_pos);
+ATF_TC_HEAD(truncl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(truncl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = truncl(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncl(+Inf) != +Inf");
+}
+
+ATF_TC(truncl_zero_neg);
+ATF_TC_HEAD(truncl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(truncl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = truncl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("truncl(-0.0) != -0.0");
+}
+
+ATF_TC(truncl_zero_pos);
+ATF_TC_HEAD(truncl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test truncl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(truncl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = truncl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("truncl(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ceil_basic);
+ ATF_TP_ADD_TC(tp, ceil_nan);
+ ATF_TP_ADD_TC(tp, ceil_inf_neg);
+ ATF_TP_ADD_TC(tp, ceil_inf_pos);
+ ATF_TP_ADD_TC(tp, ceil_zero_neg);
+ ATF_TP_ADD_TC(tp, ceil_zero_pos);
+
+ ATF_TP_ADD_TC(tp, ceilf_basic);
+ ATF_TP_ADD_TC(tp, ceilf_nan);
+ ATF_TP_ADD_TC(tp, ceilf_inf_neg);
+ ATF_TP_ADD_TC(tp, ceilf_inf_pos);
+ ATF_TP_ADD_TC(tp, ceilf_zero_neg);
+ ATF_TP_ADD_TC(tp, ceilf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, ceill_basic);
+ ATF_TP_ADD_TC(tp, ceill_nan);
+ ATF_TP_ADD_TC(tp, ceill_inf_neg);
+ ATF_TP_ADD_TC(tp, ceill_inf_pos);
+ ATF_TP_ADD_TC(tp, ceill_zero_neg);
+ ATF_TP_ADD_TC(tp, ceill_zero_pos);
+
+ ATF_TP_ADD_TC(tp, floor_basic);
+ ATF_TP_ADD_TC(tp, floor_nan);
+ ATF_TP_ADD_TC(tp, floor_inf_neg);
+ ATF_TP_ADD_TC(tp, floor_inf_pos);
+ ATF_TP_ADD_TC(tp, floor_zero_neg);
+ ATF_TP_ADD_TC(tp, floor_zero_pos);
+
+ ATF_TP_ADD_TC(tp, floorf_basic);
+ ATF_TP_ADD_TC(tp, floorf_nan);
+ ATF_TP_ADD_TC(tp, floorf_inf_neg);
+ ATF_TP_ADD_TC(tp, floorf_inf_pos);
+ ATF_TP_ADD_TC(tp, floorf_zero_neg);
+ ATF_TP_ADD_TC(tp, floorf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, floorl_basic);
+ ATF_TP_ADD_TC(tp, floorl_nan);
+ ATF_TP_ADD_TC(tp, floorl_inf_neg);
+ ATF_TP_ADD_TC(tp, floorl_inf_pos);
+ ATF_TP_ADD_TC(tp, floorl_zero_neg);
+ ATF_TP_ADD_TC(tp, floorl_zero_pos);
+
+ ATF_TP_ADD_TC(tp, trunc_basic);
+ ATF_TP_ADD_TC(tp, trunc_nan);
+ ATF_TP_ADD_TC(tp, trunc_inf_neg);
+ ATF_TP_ADD_TC(tp, trunc_inf_pos);
+ ATF_TP_ADD_TC(tp, trunc_zero_neg);
+ ATF_TP_ADD_TC(tp, trunc_zero_pos);
+
+ ATF_TP_ADD_TC(tp, truncf_basic);
+ ATF_TP_ADD_TC(tp, truncf_nan);
+ ATF_TP_ADD_TC(tp, truncf_inf_neg);
+ ATF_TP_ADD_TC(tp, truncf_inf_pos);
+ ATF_TP_ADD_TC(tp, truncf_zero_neg);
+ ATF_TP_ADD_TC(tp, truncf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, truncl_basic);
+ ATF_TP_ADD_TC(tp, truncl_nan);
+ ATF_TP_ADD_TC(tp, truncl_inf_neg);
+ ATF_TP_ADD_TC(tp, truncl_inf_pos);
+ ATF_TP_ADD_TC(tp, truncl_zero_neg);
+ ATF_TP_ADD_TC(tp, truncl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_cos.c b/lib/libm/t_cos.c
new file mode 100644
index 000000000000..d99d60810eeb
--- /dev/null
+++ b/lib/libm/t_cos.c
@@ -0,0 +1,263 @@
+/* $NetBSD: t_cos.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+
+static const struct {
+ int angle;
+ double x;
+ double y;
+} angles[] = {
+ { -180, -3.141592653589793, -1.0000000000000000 },
+ { -135, -2.356194490192345, -0.7071067811865476 },
+ { -90, -1.570796326794897, 0.0000000000000000 },
+ { -45, -0.785398163397448, 0.7071067811865476 },
+ { 0, 0.000000000000000, 1.0000000000000000 },
+ { 30, 0.523598775598299, 0.8660254037844386 },
+ { 45, 0.785398163397448, 0.7071067811865476 },
+ { 60, 1.047197551196598, 0.5000000000000000 },
+ { 90, 1.570796326794897, 0.0000000000000000 },
+ { 120, 2.094395102393195, -0.5000000000000000 },
+ { 135, 2.356194490192345, -0.7071067811865476 },
+ { 150, 2.617993877991494, -0.8660254037844386 },
+ { 180, 3.141592653589793, -1.0000000000000000 },
+ { 270, 4.712388980384690, 0.0000000000000000 },
+ { 360, 6.283185307179586, 1.0000000000000000 }
+};
+
+/*
+ * cos(3)
+ */
+ATF_TC(cos_angles);
+ATF_TC_HEAD(cos_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(cos_angles, tc)
+{
+ const double eps = 1.0e-15;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ if (fabs(cos(angles[i].x) - angles[i].y) > eps)
+ atf_tc_fail_nonfatal("cos(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(cos_nan);
+ATF_TC_HEAD(cos_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(NaN) == NaN");
+}
+
+ATF_TC_BODY(cos_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cos(x)) != 0);
+}
+
+ATF_TC(cos_inf_neg);
+ATF_TC_HEAD(cos_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(-Inf) == NaN");
+}
+
+ATF_TC_BODY(cos_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(isnan(cos(x)) != 0);
+}
+
+ATF_TC(cos_inf_pos);
+ATF_TC_HEAD(cos_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(+Inf) == NaN");
+}
+
+ATF_TC_BODY(cos_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(isnan(cos(x)) != 0);
+}
+
+
+ATF_TC(cos_zero_neg);
+ATF_TC_HEAD(cos_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(cos_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(cos(x) == 1.0);
+}
+
+ATF_TC(cos_zero_pos);
+ATF_TC_HEAD(cos_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cos(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(cos_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(cos(x) == 1.0);
+}
+
+/*
+ * cosf(3)
+ */
+ATF_TC(cosf_angles);
+ATF_TC_HEAD(cosf_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(cosf_angles, tc)
+{
+ const float eps = 1.0e-7;
+ float x, y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ x = angles[i].x;
+ y = angles[i].y;
+
+ if (fabsf(cosf(x) - y) > eps)
+ atf_tc_fail_nonfatal("cosf(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(cosf_nan);
+ATF_TC_HEAD(cosf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(NaN) == NaN");
+}
+
+ATF_TC_BODY(cosf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cosf(x)) != 0);
+}
+
+ATF_TC(cosf_inf_neg);
+ATF_TC_HEAD(cosf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(cosf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(cosf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("cosf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(cosf_inf_pos);
+ATF_TC_HEAD(cosf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(cosf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(cosf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("cosf(+Inf) != NaN");
+ }
+}
+
+
+ATF_TC(cosf_zero_neg);
+ATF_TC_HEAD(cosf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(cosf(x) == 1.0);
+}
+
+ATF_TC(cosf_zero_pos);
+ATF_TC_HEAD(cosf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosf(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(cosf(x) == 1.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cos_angles);
+ ATF_TP_ADD_TC(tp, cos_nan);
+ ATF_TP_ADD_TC(tp, cos_inf_neg);
+ ATF_TP_ADD_TC(tp, cos_inf_pos);
+ ATF_TP_ADD_TC(tp, cos_zero_neg);
+ ATF_TP_ADD_TC(tp, cos_zero_pos);
+
+ ATF_TP_ADD_TC(tp, cosf_angles);
+ ATF_TP_ADD_TC(tp, cosf_nan);
+ ATF_TP_ADD_TC(tp, cosf_inf_neg);
+ ATF_TP_ADD_TC(tp, cosf_inf_pos);
+ ATF_TP_ADD_TC(tp, cosf_zero_neg);
+ ATF_TP_ADD_TC(tp, cosf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_cosh.c b/lib/libm/t_cosh.c
new file mode 100644
index 000000000000..3f998de761bb
--- /dev/null
+++ b/lib/libm/t_cosh.c
@@ -0,0 +1,270 @@
+/* $NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+
+static const struct {
+ double x;
+ double y;
+ double e;
+} values[] = {
+ { -10, 11013.23292010332, 1e4, },
+ { -2, 3.762195691083631, 1, },
+ { -1, 1.543080634815244, 1, },
+ { -0.05, 1.001250260438369, 1, },
+ { -0.001, 1.000000500000042, 1, },
+ { 0, 1, 1, },
+ { 0.001, 1.000000500000042, 1, },
+ { 0.05, 1.001250260438369, 1, },
+ { 1, 1.543080634815244, 1, },
+ { 2, 3.762195691083631, 1, },
+ { 10, 11013.23292010332, 1e4, },
+};
+
+/*
+ * cosh(3)
+ */
+ATF_TC(cosh_inrange);
+ATF_TC_HEAD(cosh_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "cosh(x) for some values");
+}
+
+ATF_TC_BODY(cosh_inrange, tc)
+{
+ double eps;
+ double x;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-15 * values[i].e;
+
+ if (fabs(cosh(x) - y) > eps)
+ atf_tc_fail_nonfatal("cosh(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(cosh_nan);
+ATF_TC_HEAD(cosh_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(NaN) == NaN");
+}
+
+ATF_TC_BODY(cosh_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(cosh(x)) != 0);
+}
+
+ATF_TC(cosh_inf_neg);
+ATF_TC_HEAD(cosh_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(-Inf) == +Inf");
+}
+
+ATF_TC_BODY(cosh_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = cosh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cosh_inf_pos);
+ATF_TC_HEAD(cosh_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(cosh_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = cosh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(cosh_zero_neg);
+ATF_TC_HEAD(cosh_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosh_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ if (cosh(x) != 1.0)
+ atf_tc_fail_nonfatal("cosh(-0.0) != 1.0");
+}
+
+ATF_TC(cosh_zero_pos);
+ATF_TC_HEAD(cosh_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test cosh(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(cosh_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ if (cosh(x) != 1.0)
+ atf_tc_fail_nonfatal("cosh(+0.0) != 1.0");
+}
+
+/*
+ * coshf(3)
+ */
+ATF_TC(coshf_inrange);
+ATF_TC_HEAD(coshf_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "coshf(x) for some values");
+}
+
+ATF_TC_BODY(coshf_inrange, tc)
+{
+ float eps;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-6 * values[i].e;
+
+ if (fabsf(coshf(x) - y) > eps)
+ atf_tc_fail_nonfatal("coshf(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(coshf_nan);
+ATF_TC_HEAD(coshf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(NaN) == NaN");
+}
+
+ATF_TC_BODY(coshf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(coshf(x)) != 0);
+}
+
+ATF_TC(coshf_inf_neg);
+ATF_TC_HEAD(coshf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(-Inf) == +Inf");
+}
+
+ATF_TC_BODY(coshf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = coshf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(coshf_inf_pos);
+ATF_TC_HEAD(coshf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(coshf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = coshf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(coshf_zero_neg);
+ATF_TC_HEAD(coshf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(coshf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ if (coshf(x) != 1.0)
+ atf_tc_fail_nonfatal("coshf(-0.0) != 1.0");
+}
+
+ATF_TC(coshf_zero_pos);
+ATF_TC_HEAD(coshf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test coshf(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(coshf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ if (coshf(x) != 1.0)
+ atf_tc_fail_nonfatal("coshf(+0.0) != 1.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, cosh_inrange);
+ ATF_TP_ADD_TC(tp, cosh_nan);
+ ATF_TP_ADD_TC(tp, cosh_inf_neg);
+ ATF_TP_ADD_TC(tp, cosh_inf_pos);
+ ATF_TP_ADD_TC(tp, cosh_zero_neg);
+ ATF_TP_ADD_TC(tp, cosh_zero_pos);
+
+ ATF_TP_ADD_TC(tp, coshf_inrange);
+ ATF_TP_ADD_TC(tp, coshf_nan);
+ ATF_TP_ADD_TC(tp, coshf_inf_neg);
+ ATF_TP_ADD_TC(tp, coshf_inf_pos);
+ ATF_TP_ADD_TC(tp, coshf_zero_neg);
+ ATF_TP_ADD_TC(tp, coshf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_erf.c b/lib/libm/t_erf.c
new file mode 100644
index 000000000000..25bbae7834a8
--- /dev/null
+++ b/lib/libm/t_erf.c
@@ -0,0 +1,299 @@
+/* $NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_erf.c,v 1.2 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+
+/*
+ * erf(3)
+ */
+ATF_TC(erf_nan);
+ATF_TC_HEAD(erf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(NaN) == NaN");
+}
+
+ATF_TC_BODY(erf_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erf(x)) != 0);
+}
+
+ATF_TC(erf_inf_neg);
+ATF_TC_HEAD(erf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(erf_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (erf(x) != -1.0)
+ atf_tc_fail_nonfatal("erf(-Inf) != -1.0");
+}
+
+ATF_TC(erf_inf_pos);
+ATF_TC_HEAD(erf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(+Inf) == 1.0");
+}
+
+ATF_TC_BODY(erf_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ if (erf(x) != 1.0)
+ atf_tc_fail_nonfatal("erf(+Inf) != 1.0");
+}
+
+ATF_TC(erf_zero_neg);
+ATF_TC_HEAD(erf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(erf_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = erf(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("erf(-0.0) != -0.0");
+}
+
+ATF_TC(erf_zero_pos);
+ATF_TC_HEAD(erf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(erf_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = erf(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erf(+0.0) != +0.0");
+}
+
+/*
+ * erff(3)
+ */
+ATF_TC(erff_nan);
+ATF_TC_HEAD(erff_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(NaN) == NaN");
+}
+
+ATF_TC_BODY(erff_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erff(x)) != 0);
+}
+
+ATF_TC(erff_inf_neg);
+ATF_TC_HEAD(erff_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(erff_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (erff(x) != -1.0)
+ atf_tc_fail_nonfatal("erff(-Inf) != -1.0");
+}
+
+ATF_TC(erff_inf_pos);
+ATF_TC_HEAD(erff_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(+Inf) == 1.0");
+}
+
+ATF_TC_BODY(erff_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (erff(x) != 1.0)
+ atf_tc_fail_nonfatal("erff(+Inf) != 1.0");
+}
+
+ATF_TC(erff_zero_neg);
+ATF_TC_HEAD(erff_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(erff_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = erff(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("erff(-0.0) != -0.0");
+}
+
+ATF_TC(erff_zero_pos);
+ATF_TC_HEAD(erff_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erff(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(erff_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = erff(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erff(+0.0) != +0.0");
+}
+
+/*
+ * erfc(3)
+ */
+ATF_TC(erfc_nan);
+ATF_TC_HEAD(erfc_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfc(NaN) == NaN");
+}
+
+ATF_TC_BODY(erfc_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erfc(x)) != 0);
+}
+
+ATF_TC(erfc_inf_neg);
+ATF_TC_HEAD(erfc_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfc(-Inf) == 2.0");
+}
+
+ATF_TC_BODY(erfc_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (erfc(x) != 2.0)
+ atf_tc_fail_nonfatal("erfc(-Inf) != 2.0");
+}
+
+ATF_TC(erfc_inf_pos);
+ATF_TC_HEAD(erfc_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfc(+Inf) == +0.0");
+}
+
+ATF_TC_BODY(erfc_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = erfc(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erfc(+Inf) != +0.0");
+}
+
+/*
+ * erfcf(3)
+ */
+ATF_TC(erfcf_nan);
+ATF_TC_HEAD(erfcf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfcf(NaN) == NaN");
+}
+
+ATF_TC_BODY(erfcf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(erfcf(x)) != 0);
+}
+
+ATF_TC(erfcf_inf_neg);
+ATF_TC_HEAD(erfcf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfcf(-Inf) == 2.0");
+}
+
+ATF_TC_BODY(erfcf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (erfcf(x) != 2.0)
+ atf_tc_fail_nonfatal("erfcf(-Inf) != 2.0");
+}
+
+ATF_TC(erfcf_inf_pos);
+ATF_TC_HEAD(erfcf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test erfcf(+Inf) == +0.0");
+}
+
+ATF_TC_BODY(erfcf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = erfcf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("erfcf(+Inf) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, erf_nan);
+ ATF_TP_ADD_TC(tp, erf_inf_neg);
+ ATF_TP_ADD_TC(tp, erf_inf_pos);
+ ATF_TP_ADD_TC(tp, erf_zero_neg);
+ ATF_TP_ADD_TC(tp, erf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, erff_nan);
+ ATF_TP_ADD_TC(tp, erff_inf_neg);
+ ATF_TP_ADD_TC(tp, erff_inf_pos);
+ ATF_TP_ADD_TC(tp, erff_zero_neg);
+ ATF_TP_ADD_TC(tp, erff_zero_pos);
+
+ ATF_TP_ADD_TC(tp, erfc_nan);
+ ATF_TP_ADD_TC(tp, erfc_inf_neg);
+ ATF_TP_ADD_TC(tp, erfc_inf_pos);
+
+ ATF_TP_ADD_TC(tp, erfcf_nan);
+ ATF_TP_ADD_TC(tp, erfcf_inf_neg);
+ ATF_TP_ADD_TC(tp, erfcf_inf_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_exp.c b/lib/libm/t_exp.c
new file mode 100644
index 000000000000..6d410972d77c
--- /dev/null
+++ b/lib/libm/t_exp.c
@@ -0,0 +1,567 @@
+/* $NetBSD: t_exp.c,v 1.7 2014/03/17 11:08:11 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+#include "t_libm.h"
+
+/* y = exp(x) */
+static const struct {
+ double x;
+ double y;
+ double e;
+} exp_values[] = {
+ { -10, 0.4539992976248485e-4, 1e-4, },
+ { -5, 0.6737946999085467e-2, 1e-2, },
+ { -1, 0.3678794411714423, 1e-1, },
+ { -0.1, 0.9048374180359595, 1e-1, },
+ { 0, 1.0000000000000000, 1, },
+ { 0.1, 1.1051709180756477, 1, },
+ { 1, 2.7182818284590452, 1, },
+ { 5, 148.41315910257660, 1e2, },
+ { 10, 22026.465794806718, 1e4, },
+};
+
+/*
+ * exp2/exp2f(3)
+ */
+ATF_LIBM_TEST(exp2_is_nan, "Test exp2(x) == NaN")
+{
+#ifdef T_LIBM_NAN
+ T_LIBM_CHECK_NAN(0, exp2, T_LIBM_NAN);
+ T_LIBM_CHECK_NAN(0, exp2f, T_LIBM_NAN);
+#else
+ atf_tc_skip("no NaN on this machine");
+#endif
+}
+
+ATF_LIBM_TEST(exp2_is_plus_zero, "Test exp2(x) == +0.0")
+{
+#ifdef T_LIBM_MINUS_INF
+ T_LIBM_CHECK_PLUS_ZERO(0, exp2, T_LIBM_MINUS_INF);
+ T_LIBM_CHECK_PLUS_ZERO(0, exp2f, T_LIBM_MINUS_INF);
+#else
+ atf_tc_skip("no +/-Inf on this machine");
+#endif
+}
+
+ATF_LIBM_TEST(exp2_powers, "Test exp2(x) is correct for some integer x")
+{
+ static const struct {
+ double x;
+ double d_y;
+ double f_y;
+ } v[] = {
+ { +0.0, 1.0, 1.0 },
+ { -0.0, 1.0, 1.0 },
+ { 1, 0x1p1, 0x1p1 },
+ { 2, 0x1p2, 0x1p2 },
+ { 100, 0x1p100, 0x1p100 },
+ { 125, 0x1p125, 0x1p125 },
+ { 126, 0x1p126, 0x1p126 },
+#if __DBL_MAX_EXP__ > 129
+ { 127, 0x1p127, 0x1p127 },
+#endif
+#ifdef T_LIBM_PLUS_INF
+ { 128, 0x1p128, T_LIBM_PLUS_INF },
+ { 129, 0x1p129, T_LIBM_PLUS_INF },
+ { 1000, 0x1p1000, T_LIBM_PLUS_INF },
+ { 1020, 0x1p1020, T_LIBM_PLUS_INF },
+ { 1023, 0x1p1023, T_LIBM_PLUS_INF },
+ { 1024, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 1030, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 1050, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 2000, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 16383, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 16384, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+ { 16385, T_LIBM_PLUS_INF, T_LIBM_PLUS_INF },
+#endif
+ { -1, 0x1p-1, 0x1p-1 },
+ { -2, 0x1p-2, 0x1p-2 },
+ { -100, 0x1p-100, 0x1p-100 },
+ { -127, 0x1p-127, 0x1p-127 },
+ { -128, 0x1p-128, 0x1p-128 },
+#if __LDBL_MIN_EXP__ < -129
+ { -300, 0x1p-300, 0.0},
+ { -400, 0x1p-400, 0.0},
+ {-1000, 0x1p-1000, 0.0},
+ {-1022, 0x1p-1022, 0.0},
+ /* These should be denormal numbers */
+ {-1023, 0x1p-1023, 0.0},
+ {-1024, 0x1p-1024, 0.0},
+ {-1040, 0x1p-1040, 0.0},
+ {-1060, 0x1p-1060, 0.0},
+ /* This is the smallest result gcc will allow */
+ {-1074, 0x1p-1074, 0.0},
+#endif
+ {-1075, 0x0, 0.0},
+ {-1080, 0x0, 0.0},
+ {-2000, 0x0, 0.0},
+ {-16382, 0x0, 0.0},
+ {-16383, 0x0, 0.0},
+ {-16384, 0x0, 0.0},
+ };
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(v); i++) {
+ T_LIBM_CHECK(i, exp2, v[i].x, v[i].d_y, 0.0);
+ T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_y, 0.0);
+ }
+}
+
+ATF_LIBM_TEST(exp2_values, "Test exp2(x) is correct for some x")
+{
+ static const struct {
+ double x;
+ double y;
+ double d_eps;
+ double f_eps;
+ } v[] = {
+#if __DBL_MAX_EXP__ > 128
+ /* The largest double constant */
+ { 0x1.fffffffffffffp9, 0x1.ffffffffffd3ap1023,
+ 0x1p969, 0.0 },
+ /* The largest float constant */
+ { 0x1.fffffep6, 0x1.ffff4ep+127, 6e30, 0.0 },
+#endif
+#ifdef T_LIBM_PLUS_INF
+ { T_LIBM_PLUS_INF, T_LIBM_PLUS_INF, 0.0, 0.0 },
+#endif
+
+ /* The few values from the old tests */
+ /* Results from i386/amd64, d_eps needed on i386 */
+ { 1.1, 0x1.125fbee250664p+1, 0x1p-52, 0x1.8p-22 },
+ { 2.2, 0x1.2611186bae675p+2, 0x1p-51, 0x1.8p-21 },
+ { 3.3, 0x1.3b2c47bff8328p+3, 0x1p-50, 0x1.8p-20 },
+ { 4.4, 0x1.51cb453b9536ep+4, 0x1p-49, 0x1.8p-19 },
+ { 5.5, 0x1.6a09e667f3bcdp+5, 0x1p-48, 0x1.8p-18 },
+ { 6.6, 0x1.8406003b2ae5bp+6, 0x1p-47, 0x1.8p-17 },
+ /*
+ * These two currently fail for 'float'.
+ * 8.8 is definitely out by more than it should be.
+ */
+ { 7.7, 0x1.9fdf8bcce533ep+7, 0x1p-46, 0x1.8p-16 },
+ { 8.8, 0x1.bdb8cdadbe124p+8, 0x1p-45, 0x1.8p-15 },
+ };
+ unsigned int i;
+
+ for (i = 0; i < __arraycount(v); i++) {
+ T_LIBM_CHECK(i, exp2, v[i].x, v[i].y, v[i].d_eps);
+ if (i > 1)
+ T_LIBM_CHECK(i, exp2f, v[i].x, v[i].y, v[i].f_eps);
+ }
+}
+
+
+/*
+ * exp(3)
+ */
+ATF_TC(exp_nan);
+ATF_TC_HEAD(exp_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(NaN) == NaN");
+}
+
+ATF_TC_BODY(exp_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ if (isnan(exp(x)) == 0)
+ atf_tc_fail_nonfatal("exp(NaN) != NaN");
+}
+
+ATF_TC(exp_inf_neg);
+ATF_TC_HEAD(exp_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(-Inf) == +0.0");
+}
+
+ATF_TC_BODY(exp_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = exp(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("exp(-Inf) != +0.0");
+}
+
+ATF_TC(exp_inf_pos);
+ATF_TC_HEAD(exp_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(exp_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = exp(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("exp(+Inf) != +Inf");
+}
+
+ATF_TC(exp_product);
+ATF_TC_HEAD(exp_product, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected exp(x)");
+}
+
+ATF_TC_BODY(exp_product, tc)
+{
+ double eps;
+ double x;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exp_values); i++) {
+ x = exp_values[i].x;
+ y = exp_values[i].y;
+ eps = 1e-15 * exp_values[i].e;
+
+ if (fabs(exp(x) - y) > eps)
+ atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y);
+ }
+}
+
+ATF_TC(exp_zero_neg);
+ATF_TC_HEAD(exp_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(exp_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ if (fabs(exp(x) - 1.0) > 0.0)
+ atf_tc_fail_nonfatal("exp(-0.0) != 1.0");
+}
+
+ATF_TC(exp_zero_pos);
+ATF_TC_HEAD(exp_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test exp(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(exp_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ if (fabs(exp(x) - 1.0) > 0.0)
+ atf_tc_fail_nonfatal("exp(+0.0) != 1.0");
+}
+
+/*
+ * expf(3)
+ */
+ATF_TC(expf_nan);
+ATF_TC_HEAD(expf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(NaN) == NaN");
+}
+
+ATF_TC_BODY(expf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ if (isnan(expf(x)) == 0)
+ atf_tc_fail_nonfatal("expf(NaN) != NaN");
+}
+
+ATF_TC(expf_inf_neg);
+ATF_TC_HEAD(expf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(-Inf) == +0.0");
+}
+
+ATF_TC_BODY(expf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = expf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expf(-Inf) != +0.0");
+}
+
+ATF_TC(expf_inf_pos);
+ATF_TC_HEAD(expf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(expf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = expf(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expf(+Inf) != +Inf");
+}
+
+ATF_TC(expf_product);
+ATF_TC_HEAD(expf_product, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected expf(x)");
+}
+
+ATF_TC_BODY(expf_product, tc)
+{
+ float eps;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exp_values); i++) {
+ x = exp_values[i].x;
+ y = exp_values[i].y;
+ eps = 1e-6 * exp_values[i].e;
+
+ if (fabsf(expf(x) - y) > eps)
+ atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y);
+ }
+}
+
+ATF_TC(expf_zero_neg);
+ATF_TC_HEAD(expf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(-0.0) == 1.0");
+}
+
+ATF_TC_BODY(expf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ if (fabsf(expf(x) - 1.0f) > 0.0)
+ atf_tc_fail_nonfatal("expf(-0.0) != 1.0");
+}
+
+ATF_TC(expf_zero_pos);
+ATF_TC_HEAD(expf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expf(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(expf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ if (fabsf(expf(x) - 1.0f) > 0.0)
+ atf_tc_fail_nonfatal("expf(+0.0) != 1.0");
+}
+
+/*
+ * expm1(3)
+ */
+ATF_TC(expm1_nan);
+ATF_TC_HEAD(expm1_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(NaN) == NaN");
+}
+
+ATF_TC_BODY(expm1_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ if (isnan(expm1(x)) == 0)
+ atf_tc_fail_nonfatal("expm1(NaN) != NaN");
+}
+
+ATF_TC(expm1_inf_neg);
+ATF_TC_HEAD(expm1_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(-Inf) == -1");
+}
+
+ATF_TC_BODY(expm1_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ if (expm1(x) != -1.0)
+ atf_tc_fail_nonfatal("expm1(-Inf) != -1.0");
+}
+
+ATF_TC(expm1_inf_pos);
+ATF_TC_HEAD(expm1_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(expm1_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = expm1(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1(+Inf) != +Inf");
+}
+
+ATF_TC(expm1_zero_neg);
+ATF_TC_HEAD(expm1_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(expm1_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = expm1(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("expm1(-0.0) != -0.0");
+}
+
+ATF_TC(expm1_zero_pos);
+ATF_TC_HEAD(expm1_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(expm1_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = expm1(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1(+0.0) != +0.0");
+}
+
+/*
+ * expm1f(3)
+ */
+ATF_TC(expm1f_nan);
+ATF_TC_HEAD(expm1f_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(NaN) == NaN");
+}
+
+ATF_TC_BODY(expm1f_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ if (isnan(expm1f(x)) == 0)
+ atf_tc_fail_nonfatal("expm1f(NaN) != NaN");
+}
+
+ATF_TC(expm1f_inf_neg);
+ATF_TC_HEAD(expm1f_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(-Inf) == -1");
+}
+
+ATF_TC_BODY(expm1f_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (expm1f(x) != -1.0)
+ atf_tc_fail_nonfatal("expm1f(-Inf) != -1.0");
+}
+
+ATF_TC(expm1f_inf_pos);
+ATF_TC_HEAD(expm1f_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(expm1f_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = expm1f(x);
+
+ if (isinf(y) == 0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1f(+Inf) != +Inf");
+}
+
+ATF_TC(expm1f_zero_neg);
+ATF_TC_HEAD(expm1f_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(expm1f_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = expm1f(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("expm1f(-0.0) != -0.0");
+}
+
+ATF_TC(expm1f_zero_pos);
+ATF_TC_HEAD(expm1f_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test expm1f(+0.0) == 1.0");
+}
+
+ATF_TC_BODY(expm1f_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = expm1f(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("expm1f(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, exp2_is_nan);
+ ATF_TP_ADD_TC(tp, exp2_is_plus_zero);
+ ATF_TP_ADD_TC(tp, exp2_values);
+ ATF_TP_ADD_TC(tp, exp2_powers);
+
+ ATF_TP_ADD_TC(tp, exp_nan);
+ ATF_TP_ADD_TC(tp, exp_inf_neg);
+ ATF_TP_ADD_TC(tp, exp_inf_pos);
+ ATF_TP_ADD_TC(tp, exp_product);
+ ATF_TP_ADD_TC(tp, exp_zero_neg);
+ ATF_TP_ADD_TC(tp, exp_zero_pos);
+
+ ATF_TP_ADD_TC(tp, expf_nan);
+ ATF_TP_ADD_TC(tp, expf_inf_neg);
+ ATF_TP_ADD_TC(tp, expf_inf_pos);
+ ATF_TP_ADD_TC(tp, expf_product);
+ ATF_TP_ADD_TC(tp, expf_zero_neg);
+ ATF_TP_ADD_TC(tp, expf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, expm1_nan);
+ ATF_TP_ADD_TC(tp, expm1_inf_neg);
+ ATF_TP_ADD_TC(tp, expm1_inf_pos);
+ ATF_TP_ADD_TC(tp, expm1_zero_neg);
+ ATF_TP_ADD_TC(tp, expm1_zero_pos);
+
+ ATF_TP_ADD_TC(tp, expm1f_nan);
+ ATF_TP_ADD_TC(tp, expm1f_inf_neg);
+ ATF_TP_ADD_TC(tp, expm1f_inf_pos);
+ ATF_TP_ADD_TC(tp, expm1f_zero_neg);
+ ATF_TP_ADD_TC(tp, expm1f_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_fmod.c b/lib/libm/t_fmod.c
new file mode 100644
index 000000000000..7dac93deae52
--- /dev/null
+++ b/lib/libm/t_fmod.c
@@ -0,0 +1,63 @@
+/* $NetBSD: t_fmod.c,v 1.2 2014/02/27 17:26:02 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <float.h>
+#include <math.h>
+
+ATF_TC(fmod);
+ATF_TC_HEAD(fmod, tc)
+{
+ atf_tc_set_md_var(tc, "descr","Check fmod family");
+}
+
+ATF_TC_BODY(fmod, tc)
+{
+ ATF_CHECK(fmodf(2.0, 1.0) == 0);
+ ATF_CHECK(fmod(2.0, 1.0) == 0);
+ ATF_CHECK(fmodl(2.0, 1.0) == 0);
+
+ ATF_CHECK(fmodf(2.0, 0.5) == 0);
+ ATF_CHECK(fmod(2.0, 0.5) == 0);
+ ATF_CHECK(fmodl(2.0, 0.5) == 0);
+
+ ATF_CHECK(fabsf(fmodf(1.0, 0.1) - 0.1f) <= 55 * FLT_EPSILON);
+ ATF_CHECK(fabs(fmod(1.0, 0.1) - 0.1) <= 55 * DBL_EPSILON);
+ ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, fmod);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_infinity.c b/lib/libm/t_infinity.c
new file mode 100644
index 000000000000..7ac17370799c
--- /dev/null
+++ b/lib/libm/t_infinity.c
@@ -0,0 +1,119 @@
+/* $NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $ */
+
+/*-
+ * Copyright (c) 2002, 2008 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Martin Husemann <martin@NetBSD.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_infinity.c,v 1.6 2012/09/26 07:24:38 jruoho Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <float.h>
+#include <stdlib.h>
+
+ATF_TC(infinity_float);
+ATF_TC_HEAD(infinity_float, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check FPU generated infinite float values");
+}
+
+ATF_TC_BODY(infinity_float, tc)
+{
+ float v;
+
+ v = FLT_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+
+ v = -FLT_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+}
+
+ATF_TC(infinity_double);
+ATF_TC_HEAD(infinity_double, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check FPU generated infinite double values");
+}
+
+ATF_TC_BODY(infinity_double, tc)
+{
+ double v;
+
+ v = DBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+
+ v = -DBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+}
+
+ATF_TC(infinity_long_double);
+ATF_TC_HEAD(infinity_long_double, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "check FPU generated infinite long double values");
+}
+
+ATF_TC_BODY(infinity_long_double, tc)
+{
+
+#ifndef LDBL_MAX
+ atf_tc_skip("no long double support on this architecture");
+ return;
+#else
+ long double v;
+
+ v = LDBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+
+ v = -LDBL_MAX;
+ v *= v;
+ ATF_REQUIRE(isinf(v));
+ ATF_REQUIRE(fpclassify(v) == FP_INFINITE);
+#endif
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, infinity_float);
+ ATF_TP_ADD_TC(tp, infinity_double);
+ ATF_TP_ADD_TC(tp, infinity_long_double);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_ldexp.c b/lib/libm/t_ldexp.c
new file mode 100644
index 000000000000..9dd001d413fe
--- /dev/null
+++ b/lib/libm/t_ldexp.c
@@ -0,0 +1,481 @@
+/* $NetBSD: t_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_ldexp.c,v 1.13 2014/03/12 21:40:07 martin Exp $");
+
+#include <sys/param.h>
+
+#include <atf-c.h>
+#include <atf-c/config.h>
+
+#include <math.h>
+#include <limits.h>
+#include <stdio.h>
+#include <string.h>
+
+#define SKIP 9999
+#define FORMAT "%23.23lg"
+
+static const int exps[] = { 0, 1, -1, 100, -100 };
+
+struct ldexp_test {
+ double x;
+ int exp1;
+ int exp2;
+ const char *result;
+};
+
+struct ldexp_test ldexp_basic[] = {
+ { 1.0, 5, SKIP, " 32" },
+ { 1.0, 1022, SKIP, "4.4942328371557897693233e+307" },
+ { 1.0, 1023, -1, "4.4942328371557897693233e+307" },
+ { 1.0, 1023, SKIP, "8.9884656743115795386465e+307" },
+ { 1.0, 1022, 1, "8.9884656743115795386465e+307" },
+ { 1.0, -1022, 2045, "8.9884656743115795386465e+307" },
+ { 1.0, -5, SKIP, " 0.03125" },
+ { 1.0, -1021, SKIP, "4.4501477170144027661805e-308" },
+ { 1.0, -1022, 1, "4.4501477170144027661805e-308" },
+ { 1.0, -1022, SKIP, "2.2250738585072013830902e-308" },
+ { 1.0, -1021, -1, "2.2250738585072013830902e-308" },
+ { 1.0, 1023, -2045, "2.2250738585072013830902e-308" },
+ { 1.0, 1023, -1023, " 1" },
+ { 1.0, -1022, 1022, " 1" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_zero[] = {
+ { 0.0, -1, SKIP, " 0" },
+ { 0.0, 0, SKIP, " 0" },
+ { 0.0, 1, SKIP, " 0" },
+ { 0.0, 1024, SKIP, " 0" },
+ { 0.0, 1025, SKIP, " 0" },
+ { 0.0, -1023, SKIP, " 0" },
+ { 0.0, -1024, SKIP, " 0" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_infinity[] = {
+ { 1.0, 1024, -1, " inf" },
+ { 1.0, 1024, 0, " inf" },
+ { 1.0, 1024, 1, " inf" },
+ { -1.0, 1024, -1, " -inf" },
+ { -1.0, 1024, 0, " -inf" },
+ { -1.0, 1024, 1, " -inf" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_overflow[] = {
+ { 1.0, 1024, SKIP, " inf" },
+ { 1.0, 1023, 1, " inf" },
+ { 1.0, -1022, 2046, " inf" },
+ { 1.0, 1025, SKIP, " inf" },
+ { -1.0, 1024, SKIP, " -inf" },
+ { -1.0, 1023, 1, " -inf" },
+ { -1.0, -1022, 2046, " -inf" },
+ { -1.0, 1025, SKIP, " -inf" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_denormal[] = {
+ { 1.0, -1023, SKIP, "1.1125369292536006915451e-308" },
+ { 1.0, -1022, -1, "1.1125369292536006915451e-308" },
+ { 1.0, 1023, -2046, "1.1125369292536006915451e-308" },
+ { 1.0, -1024, SKIP, "5.5626846462680034577256e-309" },
+ { 1.0, -1074, SKIP, "4.9406564584124654417657e-324" },
+ { -1.0, -1023, SKIP, "-1.1125369292536006915451e-308" },
+ { -1.0, -1022, -1, "-1.1125369292536006915451e-308" },
+ { -1.0, 1023, -2046, "-1.1125369292536006915451e-308" },
+ { -1.0, -1024, SKIP, "-5.5626846462680034577256e-309" },
+ { -1.0, -1074, SKIP, "-4.9406564584124654417657e-324" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_underflow[] = {
+ { 1.0, -1075, SKIP, " 0" },
+ { 1.0, -1074, -1, " 0" },
+ { 1.0, 1023, -2098, " 0" },
+ { 1.0, -1076, SKIP, " 0" },
+ { -1.0, -1075, SKIP, " -0" },
+ { -1.0, -1074, -1, " -0" },
+ { -1.0, 1023, -2098, " -0" },
+ { -1.0, -1076, SKIP, " -0" },
+ { 0, 0, 0, NULL }
+};
+
+struct ldexp_test ldexp_denormal_large[] = {
+ { 1.0, -1028, 1024, " 0.0625" },
+ { 1.0, -1028, 1025, " 0.125" },
+ { 1.0, -1028, 1026, " 0.25" },
+ { 1.0, -1028, 1027, " 0.5" },
+ { 1.0, -1028, 1028, " 1" },
+ { 1.0, -1028, 1029, " 2" },
+ { 1.0, -1028, 1030, " 4" },
+ { 1.0, -1028, 1040, " 4096" },
+ { 1.0, -1028, 1050, " 4194304" },
+ { 1.0, -1028, 1060, " 4294967296" },
+ { 1.0, -1028, 1100, " 4722366482869645213696" },
+ { 1.0, -1028, 1200, "5.9863107065073783529623e+51" },
+ { 1.0, -1028, 1300, "7.5885503602567541832791e+81" },
+ { 1.0, -1028, 1400, "9.6196304190416209014353e+111" },
+ { 1.0, -1028, 1500, "1.2194330274671844653834e+142" },
+ { 1.0, -1028, 1600, "1.5458150092069033378781e+172" },
+ { 1.0, -1028, 1700, "1.9595533242629369747791e+202" },
+ { 1.0, -1028, 1800, "2.4840289476811342962384e+232" },
+ { 1.0, -1028, 1900, "3.1488807865122869393369e+262" },
+ { 1.0, -1028, 2000, "3.9916806190694396233127e+292" },
+ { 1.0, -1028, 2046, "2.808895523222368605827e+306" },
+ { 1.0, -1028, 2047, "5.6177910464447372116541e+306" },
+ { 1.0, -1028, 2048, "1.1235582092889474423308e+307" },
+ { 1.0, -1028, 2049, "2.2471164185778948846616e+307" },
+ { 1.0, -1028, 2050, "4.4942328371557897693233e+307" },
+ { 1.0, -1028, 2051, "8.9884656743115795386465e+307" },
+ { 0, 0, 0, NULL }
+};
+
+static void
+run_test(struct ldexp_test *table)
+{
+ char outbuf[64];
+ size_t i;
+ double v;
+
+ for (i = 0; table->result != NULL; table++, i++) {
+
+ v = ldexp(table->x, table->exp1);
+
+ if (table->exp2 == SKIP)
+ continue;
+
+ v = ldexp(v, table->exp2);
+
+ (void)snprintf(outbuf, sizeof(outbuf), FORMAT, v);
+
+ ATF_CHECK_STREQ_MSG(table->result, outbuf,
+ "Entry %zu:\n\tExp: \"%s\"\n\tAct: \"%s\"",
+ i, table->result, outbuf);
+ }
+}
+
+/*
+ * ldexp(3)
+ */
+ATF_TC(ldexp_exp2);
+ATF_TC_HEAD(ldexp_exp2, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(x, n) == x * exp2(n)");
+}
+
+ATF_TC_BODY(ldexp_exp2, tc)
+{
+ const double n[] = { 1, 2, 3, 10, 50, 100 };
+#if __DBL_MIN_10_EXP__ <= -40
+ const double eps = 1.0e-40;
+#else
+ const double eps = __DBL_MIN__*4.0;
+#endif
+ const double x = 12.0;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(n); i++) {
+
+ y = ldexp(x, n[i]);
+
+ if (fabs(y - (x * exp2(n[i]))) > eps) {
+ atf_tc_fail_nonfatal("ldexp(%0.01f, %0.01f) "
+ "!= %0.01f * exp2(%0.01f)", x, n[i], x, n[i]);
+ }
+ }
+}
+
+ATF_TC(ldexp_nan);
+ATF_TC_HEAD(ldexp_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(NaN) == NaN");
+}
+
+ATF_TC_BODY(ldexp_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexp(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(ldexp_inf_neg);
+ATF_TC_HEAD(ldexp_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ldexp_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexp(x, exps[i]) == x);
+}
+
+ATF_TC(ldexp_inf_pos);
+ATF_TC_HEAD(ldexp_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ldexp_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexp(x, exps[i]) == x);
+}
+
+ATF_TC(ldexp_zero_neg);
+ATF_TC_HEAD(ldexp_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ldexp_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexp(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(ldexp_zero_pos);
+ATF_TC_HEAD(ldexp_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexp(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ldexp_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexp(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+/*
+ * ldexpf(3)
+ */
+
+ATF_TC(ldexpf_exp2f);
+ATF_TC_HEAD(ldexpf_exp2f, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(x, n) == x * exp2f(n)");
+}
+
+ATF_TC_BODY(ldexpf_exp2f, tc)
+{
+ const float n[] = { 1, 2, 3, 10, 50, 100 };
+ const float eps = 1.0e-9;
+ const float x = 12.0;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(n); i++) {
+
+ y = ldexpf(x, n[i]);
+
+ if (fabsf(y - (x * exp2f(n[i]))) > eps) {
+ atf_tc_fail_nonfatal("ldexpf(%0.01f, %0.01f) "
+ "!= %0.01f * exp2f(%0.01f)", x, n[i], x, n[i]);
+ }
+ }
+}
+
+ATF_TC(ldexpf_nan);
+ATF_TC_HEAD(ldexpf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(NaN) == NaN");
+}
+
+ATF_TC_BODY(ldexpf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexpf(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(ldexpf_inf_neg);
+ATF_TC_HEAD(ldexpf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(ldexpf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexpf(x, exps[i]) == x);
+}
+
+ATF_TC(ldexpf_inf_pos);
+ATF_TC_HEAD(ldexpf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(ldexpf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(ldexpf(x, exps[i]) == x);
+}
+
+ATF_TC(ldexpf_zero_neg);
+ATF_TC_HEAD(ldexpf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(ldexpf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexpf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(ldexpf_zero_pos);
+ATF_TC_HEAD(ldexpf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test ldexpf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(ldexpf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = ldexpf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+#define TEST(name, desc) \
+ ATF_TC(name); \
+ ATF_TC_HEAD(name, tc) \
+ { \
+ \
+ atf_tc_set_md_var(tc, "descr", \
+ "Test ldexp(3) for " ___STRING(desc)); \
+ } \
+ ATF_TC_BODY(name, tc) \
+ { \
+ if (strcmp("vax", MACHINE_ARCH) == 0) \
+ atf_tc_skip("Test not valid for " MACHINE_ARCH); \
+ run_test(name); \
+ }
+
+TEST(ldexp_basic, basics)
+TEST(ldexp_zero, zero)
+TEST(ldexp_infinity, infinity)
+TEST(ldexp_overflow, overflow)
+TEST(ldexp_denormal, denormal)
+TEST(ldexp_denormal_large, large)
+TEST(ldexp_underflow, underflow)
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, ldexp_basic);
+ ATF_TP_ADD_TC(tp, ldexp_zero);
+ ATF_TP_ADD_TC(tp, ldexp_infinity);
+ ATF_TP_ADD_TC(tp, ldexp_overflow);
+ ATF_TP_ADD_TC(tp, ldexp_denormal);
+ ATF_TP_ADD_TC(tp, ldexp_underflow);
+ ATF_TP_ADD_TC(tp, ldexp_denormal_large);
+
+ ATF_TP_ADD_TC(tp, ldexp_exp2);
+ ATF_TP_ADD_TC(tp, ldexp_nan);
+ ATF_TP_ADD_TC(tp, ldexp_inf_neg);
+ ATF_TP_ADD_TC(tp, ldexp_inf_pos);
+ ATF_TP_ADD_TC(tp, ldexp_zero_neg);
+ ATF_TP_ADD_TC(tp, ldexp_zero_pos);
+
+ ATF_TP_ADD_TC(tp, ldexpf_exp2f);
+ ATF_TP_ADD_TC(tp, ldexpf_nan);
+ ATF_TP_ADD_TC(tp, ldexpf_inf_neg);
+ ATF_TP_ADD_TC(tp, ldexpf_inf_pos);
+ ATF_TP_ADD_TC(tp, ldexpf_zero_neg);
+ ATF_TP_ADD_TC(tp, ldexpf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_libm.h b/lib/libm/t_libm.h
new file mode 100644
index 000000000000..34e3cb28abf5
--- /dev/null
+++ b/lib/libm/t_libm.h
@@ -0,0 +1,62 @@
+/* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */
+
+/*
+ * Check result of fn(arg) is correct within the bounds.
+ * Should be ok to do the checks using 'double' for 'float' functions.
+ * On i386 float and double values are returned on the x87 stack and might
+ * be out of range for the function - so save and print as 'long double'.
+ * (otherwise you can get 'inf != inf' reported!)
+ */
+#define T_LIBM_CHECK(subtest, fn, arg, expect_, epsilon_) do { \
+ long double epsilon = epsilon_; \
+ long double expect = expect_; \
+ long double r = fn(arg); \
+ long double e = fabsl(r - expect); \
+ if (r != expect && e > epsilon) \
+ atf_tc_fail_nonfatal( \
+ "subtest %u: " #fn "(%g) is %Lg (%.14La) " \
+ "not %Lg (%.13La), error %Lg (%.6La) > %Lg", \
+ subtest, arg, r, r, expect, expect, e, e, epsilon); \
+ } while (0)
+
+/* Check that the result of fn(arg) is NaN */
+#ifndef __vax__
+#define T_LIBM_CHECK_NAN(subtest, fn, arg) do { \
+ double r = fn(arg); \
+ if (!isnan(r)) \
+ atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not NaN", \
+ subtest, arg, r); \
+ } while (0)
+#else
+/* vax doesn't support NaN */
+#define T_LIBM_CHECK_NAN(subtest, fn, arg) (void)(arg)
+#endif
+
+/* Check that the result of fn(arg) is +0.0 */
+#define T_LIBM_CHECK_PLUS_ZERO(subtest, fn, arg) do { \
+ double r = fn(arg); \
+ if (fabs(r) > 0.0 || signbit(r) != 0) \
+ atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not +0.0", \
+ subtest, arg, r); \
+ } while (0)
+
+/* Check that the result of fn(arg) is -0.0 */
+#define T_LIBM_CHECK_MINUS_ZERO(subtest, fn, arg) do { \
+ double r = fn(arg); \
+ if (fabs(r) > 0.0 || signbit(r) == 0) \
+ atf_tc_fail_nonfatal("subtest %u: " #fn "(%g) is %g not -0.0", \
+ subtest, arg, r); \
+ } while (0)
+
+/* Some useful constants (for test vectors) */
+#ifndef __vax__ /* no NAN nor +/- INF on vax */
+#define T_LIBM_NAN (0.0 / 0.0)
+#define T_LIBM_PLUS_INF (+1.0 / 0.0)
+#define T_LIBM_MINUS_INF (-1.0 / 0.0)
+#endif
+
+/* One line definition of a simple test */
+#define ATF_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)
diff --git a/lib/libm/t_log.c b/lib/libm/t_log.c
new file mode 100644
index 000000000000..de5a1c649451
--- /dev/null
+++ b/lib/libm/t_log.c
@@ -0,0 +1,885 @@
+/* $NetBSD: t_log.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_log.c,v 1.11 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <atf-c/config.h>
+
+#include <math.h>
+#include <stdio.h>
+#include <string.h>
+
+/*
+ * log10(3)
+ */
+ATF_TC(log10_base);
+ATF_TC_HEAD(log10_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(10) == 1");
+}
+
+ATF_TC_BODY(log10_base, tc)
+{
+ ATF_CHECK(log10(10.0) == 1.0);
+}
+
+ATF_TC(log10_nan);
+ATF_TC_HEAD(log10_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(NaN) == NaN");
+}
+
+ATF_TC_BODY(log10_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log10(x)) != 0);
+}
+
+ATF_TC(log10_inf_neg);
+ATF_TC_HEAD(log10_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log10_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log10(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log10_inf_pos);
+ATF_TC_HEAD(log10_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log10_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log10(x) == x);
+}
+
+ATF_TC(log10_one_pos);
+ATF_TC_HEAD(log10_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log10_one_pos, tc)
+{
+ const double x = log10(1.0);
+ const double y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log10_zero_neg);
+ATF_TC_HEAD(log10_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(-0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log10_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log10(x) == -HUGE_VAL);
+}
+
+ATF_TC(log10_zero_pos);
+ATF_TC_HEAD(log10_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10(+0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log10_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log10(x) == -HUGE_VAL);
+}
+
+/*
+ * log10f(3)
+ */
+ATF_TC(log10f_base);
+ATF_TC_HEAD(log10f_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(10) == 1");
+}
+
+ATF_TC_BODY(log10f_base, tc)
+{
+ ATF_CHECK(log10f(10.0) == 1.0);
+}
+
+ATF_TC(log10f_nan);
+ATF_TC_HEAD(log10f_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(NaN) == NaN");
+}
+
+ATF_TC_BODY(log10f_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log10f(x)) != 0);
+}
+
+ATF_TC(log10f_inf_neg);
+ATF_TC_HEAD(log10f_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log10f_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = log10f(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log10f_inf_pos);
+ATF_TC_HEAD(log10f_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log10f_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+#if defined(__alpha__)
+ atf_tc_expect_fail("PR port-alpha/46301");
+#endif
+
+ ATF_CHECK(log10f(x) == x);
+}
+
+ATF_TC(log10f_one_pos);
+ATF_TC_HEAD(log10f_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log10f_one_pos, tc)
+{
+ const float x = log10f(1.0);
+ const float y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log10f_zero_neg);
+ATF_TC_HEAD(log10f_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(-0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log10f_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(log10f(x) == -HUGE_VALF);
+}
+
+ATF_TC(log10f_zero_pos);
+ATF_TC_HEAD(log10f_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log10f(+0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log10f_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(log10f(x) == -HUGE_VALF);
+}
+
+/*
+ * log1p(3)
+ */
+ATF_TC(log1p_nan);
+ATF_TC_HEAD(log1p_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(NaN) == NaN");
+}
+
+ATF_TC_BODY(log1p_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log1p(x)) != 0);
+}
+
+ATF_TC(log1p_inf_neg);
+ATF_TC_HEAD(log1p_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log1p_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log1p(x);
+
+ if (isnan(y) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1p(-Inf) != NaN");
+ }
+}
+
+ATF_TC(log1p_inf_pos);
+ATF_TC_HEAD(log1p_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log1p_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log1p(x) == x);
+}
+
+ATF_TC(log1p_one_neg);
+ATF_TC_HEAD(log1p_one_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(-1.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log1p_one_neg, tc)
+{
+ const double x = log1p(-1.0);
+
+ if (x != -HUGE_VAL) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1p(-1.0) != -HUGE_VAL");
+ }
+}
+
+ATF_TC(log1p_zero_neg);
+ATF_TC_HEAD(log1p_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(log1p_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log1p(x) == x);
+}
+
+ATF_TC(log1p_zero_pos);
+ATF_TC_HEAD(log1p_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1p(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(log1p_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log1p(x) == x);
+}
+
+/*
+ * log1pf(3)
+ */
+ATF_TC(log1pf_nan);
+ATF_TC_HEAD(log1pf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(NaN) == NaN");
+}
+
+ATF_TC_BODY(log1pf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log1pf(x)) != 0);
+}
+
+ATF_TC(log1pf_inf_neg);
+ATF_TC_HEAD(log1pf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log1pf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = log1pf(x);
+
+ if (isnan(y) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1pf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(log1pf_inf_pos);
+ATF_TC_HEAD(log1pf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log1pf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ ATF_CHECK(log1pf(x) == x);
+}
+
+ATF_TC(log1pf_one_neg);
+ATF_TC_HEAD(log1pf_one_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(-1.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log1pf_one_neg, tc)
+{
+ const float x = log1pf(-1.0);
+
+ if (x != -HUGE_VALF) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("log1pf(-1.0) != -HUGE_VALF");
+ }
+}
+
+ATF_TC(log1pf_zero_neg);
+ATF_TC_HEAD(log1pf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(log1pf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(log1pf(x) == x);
+}
+
+ATF_TC(log1pf_zero_pos);
+ATF_TC_HEAD(log1pf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log1pf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(log1pf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(log1pf(x) == x);
+}
+
+/*
+ * log2(3)
+ */
+ATF_TC(log2_base);
+ATF_TC_HEAD(log2_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(2) == 1");
+}
+
+ATF_TC_BODY(log2_base, tc)
+{
+ ATF_CHECK(log2(2.0) == 1.0);
+}
+
+ATF_TC(log2_nan);
+ATF_TC_HEAD(log2_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(NaN) == NaN");
+}
+
+ATF_TC_BODY(log2_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log2(x)) != 0);
+}
+
+ATF_TC(log2_inf_neg);
+ATF_TC_HEAD(log2_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log2_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log2(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log2_inf_pos);
+ATF_TC_HEAD(log2_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log2_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log2(x) == x);
+}
+
+ATF_TC(log2_one_pos);
+ATF_TC_HEAD(log2_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log2_one_pos, tc)
+{
+ const double x = log2(1.0);
+ const double y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log2_zero_neg);
+ATF_TC_HEAD(log2_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(-0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log2_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log2(x) == -HUGE_VAL);
+}
+
+ATF_TC(log2_zero_pos);
+ATF_TC_HEAD(log2_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2(+0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log2_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log2(x) == -HUGE_VAL);
+}
+
+/*
+ * log2f(3)
+ */
+ATF_TC(log2f_base);
+ATF_TC_HEAD(log2f_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(2) == 1");
+}
+
+ATF_TC_BODY(log2f_base, tc)
+{
+ ATF_CHECK(log2f(2.0) == 1.0);
+}
+
+ATF_TC(log2f_nan);
+ATF_TC_HEAD(log2f_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(NaN) == NaN");
+}
+
+ATF_TC_BODY(log2f_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log2f(x)) != 0);
+}
+
+ATF_TC(log2f_inf_neg);
+ATF_TC_HEAD(log2f_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log2f_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = log2f(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log2f_inf_pos);
+ATF_TC_HEAD(log2f_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log2f_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+#if defined(__alpha__)
+ atf_tc_expect_fail("PR port-alpha/46301");
+#endif
+
+ ATF_CHECK(log2f(x) == x);
+}
+
+ATF_TC(log2f_one_pos);
+ATF_TC_HEAD(log2f_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log2f_one_pos, tc)
+{
+ const float x = log2f(1.0);
+ const float y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log2f_zero_neg);
+ATF_TC_HEAD(log2f_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(-0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log2f_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(log2f(x) == -HUGE_VALF);
+}
+
+ATF_TC(log2f_zero_pos);
+ATF_TC_HEAD(log2f_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log2f(+0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(log2f_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(log2f(x) == -HUGE_VALF);
+}
+
+/*
+ * log(3)
+ */
+ATF_TC(log_base);
+ATF_TC_HEAD(log_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(e) == 1");
+}
+
+ATF_TC_BODY(log_base, tc)
+{
+ const double eps = 1.0e-38;
+
+ if (fabs(log(M_E) - 1.0) > eps)
+ atf_tc_fail_nonfatal("log(e) != 1");
+}
+
+ATF_TC(log_nan);
+ATF_TC_HEAD(log_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(NaN) == NaN");
+}
+
+ATF_TC_BODY(log_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(log(x)) != 0);
+}
+
+ATF_TC(log_inf_neg);
+ATF_TC_HEAD(log_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(-Inf) == NaN");
+}
+
+ATF_TC_BODY(log_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ const double y = log(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(log_inf_pos);
+ATF_TC_HEAD(log_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(log_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(log(x) == x);
+}
+
+ATF_TC(log_one_pos);
+ATF_TC_HEAD(log_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(1.0) == +0.0");
+}
+
+ATF_TC_BODY(log_one_pos, tc)
+{
+ const double x = log(1.0);
+ const double y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(log_zero_neg);
+ATF_TC_HEAD(log_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(-0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(log(x) == -HUGE_VAL);
+}
+
+ATF_TC(log_zero_pos);
+ATF_TC_HEAD(log_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test log(+0.0) == -HUGE_VAL");
+}
+
+ATF_TC_BODY(log_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(log(x) == -HUGE_VAL);
+}
+
+/*
+ * logf(3)
+ */
+ATF_TC(logf_base);
+ATF_TC_HEAD(logf_base, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(e) == 1");
+}
+
+ATF_TC_BODY(logf_base, tc)
+{
+ const float eps = 1.0e-7;
+
+ if (fabsf(logf(M_E) - 1.0f) > eps)
+ atf_tc_fail_nonfatal("logf(e) != 1");
+}
+
+ATF_TC(logf_nan);
+ATF_TC_HEAD(logf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(NaN) == NaN");
+}
+
+ATF_TC_BODY(logf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(logf(x)) != 0);
+}
+
+ATF_TC(logf_inf_neg);
+ATF_TC_HEAD(logf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(logf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ const float y = logf(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(logf_inf_pos);
+ATF_TC_HEAD(logf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(logf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+#if defined(__alpha__)
+ atf_tc_expect_fail("PR port-alpha/46301");
+#endif
+
+ ATF_CHECK(logf(x) == x);
+}
+
+ATF_TC(logf_one_pos);
+ATF_TC_HEAD(logf_one_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(1.0) == +0.0");
+}
+
+ATF_TC_BODY(logf_one_pos, tc)
+{
+ const float x = logf(1.0);
+ const float y = 0.0L;
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(logf_zero_neg);
+ATF_TC_HEAD(logf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(-0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(logf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(logf(x) == -HUGE_VALF);
+}
+
+ATF_TC(logf_zero_pos);
+ATF_TC_HEAD(logf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test logf(+0.0) == -HUGE_VALF");
+}
+
+ATF_TC_BODY(logf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(logf(x) == -HUGE_VALF);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, log10_base);
+ ATF_TP_ADD_TC(tp, log10_nan);
+ ATF_TP_ADD_TC(tp, log10_inf_neg);
+ ATF_TP_ADD_TC(tp, log10_inf_pos);
+ ATF_TP_ADD_TC(tp, log10_one_pos);
+ ATF_TP_ADD_TC(tp, log10_zero_neg);
+ ATF_TP_ADD_TC(tp, log10_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log10f_base);
+ ATF_TP_ADD_TC(tp, log10f_nan);
+ ATF_TP_ADD_TC(tp, log10f_inf_neg);
+ ATF_TP_ADD_TC(tp, log10f_inf_pos);
+ ATF_TP_ADD_TC(tp, log10f_one_pos);
+ ATF_TP_ADD_TC(tp, log10f_zero_neg);
+ ATF_TP_ADD_TC(tp, log10f_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log1p_nan);
+ ATF_TP_ADD_TC(tp, log1p_inf_neg);
+ ATF_TP_ADD_TC(tp, log1p_inf_pos);
+ ATF_TP_ADD_TC(tp, log1p_one_neg);
+ ATF_TP_ADD_TC(tp, log1p_zero_neg);
+ ATF_TP_ADD_TC(tp, log1p_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log1pf_nan);
+ ATF_TP_ADD_TC(tp, log1pf_inf_neg);
+ ATF_TP_ADD_TC(tp, log1pf_inf_pos);
+ ATF_TP_ADD_TC(tp, log1pf_one_neg);
+ ATF_TP_ADD_TC(tp, log1pf_zero_neg);
+ ATF_TP_ADD_TC(tp, log1pf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log2_base);
+ ATF_TP_ADD_TC(tp, log2_nan);
+ ATF_TP_ADD_TC(tp, log2_inf_neg);
+ ATF_TP_ADD_TC(tp, log2_inf_pos);
+ ATF_TP_ADD_TC(tp, log2_one_pos);
+ ATF_TP_ADD_TC(tp, log2_zero_neg);
+ ATF_TP_ADD_TC(tp, log2_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log2f_base);
+ ATF_TP_ADD_TC(tp, log2f_nan);
+ ATF_TP_ADD_TC(tp, log2f_inf_neg);
+ ATF_TP_ADD_TC(tp, log2f_inf_pos);
+ ATF_TP_ADD_TC(tp, log2f_one_pos);
+ ATF_TP_ADD_TC(tp, log2f_zero_neg);
+ ATF_TP_ADD_TC(tp, log2f_zero_pos);
+
+ ATF_TP_ADD_TC(tp, log_base);
+ ATF_TP_ADD_TC(tp, log_nan);
+ ATF_TP_ADD_TC(tp, log_inf_neg);
+ ATF_TP_ADD_TC(tp, log_inf_pos);
+ ATF_TP_ADD_TC(tp, log_one_pos);
+ ATF_TP_ADD_TC(tp, log_zero_neg);
+ ATF_TP_ADD_TC(tp, log_zero_pos);
+
+ ATF_TP_ADD_TC(tp, logf_base);
+ ATF_TP_ADD_TC(tp, logf_nan);
+ ATF_TP_ADD_TC(tp, logf_inf_neg);
+ ATF_TP_ADD_TC(tp, logf_inf_pos);
+ ATF_TP_ADD_TC(tp, logf_one_pos);
+ ATF_TP_ADD_TC(tp, logf_zero_neg);
+ ATF_TP_ADD_TC(tp, logf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_modf.c b/lib/libm/t_modf.c
new file mode 100644
index 000000000000..a856b15d1aab
--- /dev/null
+++ b/lib/libm/t_modf.c
@@ -0,0 +1,68 @@
+/* $NetBSD: t_modf.c,v 1.1 2014/06/16 12:54:43 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2014 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <float.h>
+#include <math.h>
+
+ATF_TC(modf);
+ATF_TC_HEAD(modf, tc)
+{
+ atf_tc_set_md_var(tc, "descr","Check modf family");
+}
+
+ATF_TC_BODY(modf, tc)
+{
+ float basef;
+ double base;
+ long double basel;
+ ATF_CHECK(modff(1.0, &basef) == 0.0);
+ ATF_CHECK(basef == 1.0);
+ ATF_CHECK(modf(1.0, &base) == 0.0);
+ ATF_CHECK(base == 1.0);
+ ATF_CHECK(modfl(1.0, &basel) == 0.0);
+ ATF_CHECK(basel == 1.0);
+
+ ATF_CHECK(modff(-1 - FLT_EPSILON, &basef) == -FLT_EPSILON);
+ ATF_CHECK(basef == -1.0);
+ ATF_CHECK(modf(-1 - DBL_EPSILON, &base) == -DBL_EPSILON);
+ ATF_CHECK(base == -1.0);
+ ATF_CHECK(modfl(-1 - LDBL_EPSILON, &basel) == -LDBL_EPSILON);
+ ATF_CHECK(basel == -1.0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, modf);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_pow.c b/lib/libm/t_pow.c
new file mode 100644
index 000000000000..62b7235e7640
--- /dev/null
+++ b/lib/libm/t_pow.c
@@ -0,0 +1,669 @@
+/* $NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_pow.c,v 1.3 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+
+/*
+ * pow(3)
+ */
+ATF_TC(pow_nan_x);
+ATF_TC_HEAD(pow_nan_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(NaN, y) == NaN");
+}
+
+ATF_TC_BODY(pow_nan_x, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(pow(x, 2.0)) != 0);
+}
+
+ATF_TC(pow_nan_y);
+ATF_TC_HEAD(pow_nan_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, NaN) == NaN");
+}
+
+ATF_TC_BODY(pow_nan_y, tc)
+{
+ const double y = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(pow(2.0, y)) != 0);
+}
+
+ATF_TC(pow_inf_neg_x);
+ATF_TC_HEAD(pow_inf_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(-Inf, y) == +-Inf || +-0.0");
+}
+
+ATF_TC_BODY(pow_inf_neg_x, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double z;
+
+ /*
+ * If y is odd, y > 0, and x is -Inf, -Inf is returned.
+ * If y is even, y > 0, and x is -Inf, +Inf is returned.
+ */
+ z = pow(x, 3.0);
+
+ if (isinf(z) == 0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("pow(-Inf, 3.0) != -Inf");
+
+ z = pow(x, 4.0);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(-Inf, 4.0) != +Inf");
+
+ /*
+ * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
+ * If y is even, y < 0, and x is -Inf, +0.0 is returned.
+ */
+ z = pow(x, -3.0);
+
+ if (fabs(z) > 0.0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("pow(-Inf, -3.0) != -0.0");
+
+ z = pow(x, -4.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(-Inf -4.0) != +0.0");
+}
+
+ATF_TC(pow_inf_neg_y);
+ATF_TC_HEAD(pow_inf_neg_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, -Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(pow_inf_neg_y, tc)
+{
+ const double y = -1.0L / 0.0L;
+ double z;
+
+ /*
+ * If |x| < 1 and y is -Inf, +Inf is returned.
+ * If |x| > 1 and y is -Inf, +0.0 is returned.
+ */
+ z = pow(0.1, y);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(0.1, -Inf) != +Inf");
+
+ z = pow(1.1, y);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(1.1, -Inf) != +0.0");
+}
+
+ATF_TC(pow_inf_pos_x);
+ATF_TC_HEAD(pow_inf_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(+Inf, y) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(pow_inf_pos_x, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double z;
+
+ /*
+ * For y < 0, if x is +Inf, +0.0 is returned.
+ * For y > 0, if x is +Inf, +Inf is returned.
+ */
+ z = pow(x, -2.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+Inf, -2.0) != +0.0");
+
+ z = pow(x, 2.0);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+Inf, 2.0) != +Inf");
+}
+
+ATF_TC(pow_inf_pos_y);
+ATF_TC_HEAD(pow_inf_pos_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, +Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(pow_inf_pos_y, tc)
+{
+ const double y = 1.0L / 0.0L;
+ double z;
+
+ /*
+ * If |x| < 1 and y is +Inf, +0.0 is returned.
+ * If |x| > 1 and y is +Inf, +Inf is returned.
+ */
+ z = pow(0.1, y);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(0.1, +Inf) != +0.0");
+
+ z = pow(1.1, y);
+
+ if (isinf(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(1.1, +Inf) != +Inf");
+}
+
+ATF_TC(pow_one_neg_x);
+ATF_TC_HEAD(pow_one_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(-1.0, +-Inf) == 1.0");
+}
+
+ATF_TC_BODY(pow_one_neg_x, tc)
+{
+ const double infp = 1.0L / 0.0L;
+ const double infn = -1.0L / 0.0L;
+
+ /*
+ * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
+ */
+ ATF_REQUIRE(isinf(infp) != 0);
+ ATF_REQUIRE(isinf(infn) != 0);
+
+ if (pow(-1.0, infp) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("pow(-1.0, +Inf) != 1.0");
+ }
+
+ if (pow(-1.0, infn) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("pow(-1.0, -Inf) != 1.0");
+ }
+}
+
+ATF_TC(pow_one_pos_x);
+ATF_TC_HEAD(pow_one_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(1.0, y) == 1.0");
+}
+
+ATF_TC_BODY(pow_one_pos_x, tc)
+{
+ const double y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
+ const double z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of y (including NaN),
+ * if x is 1.0, 1.0 shall be returned.
+ */
+ if (pow(1.0, z) != 1.0)
+ atf_tc_fail_nonfatal("pow(1.0, NaN) != 1.0");
+
+ for (i = 0; i < __arraycount(y); i++) {
+
+ if (pow(1.0, y[i]) != 1.0)
+ atf_tc_fail_nonfatal("pow(1.0, %0.01f) != 1.0", y[i]);
+ }
+}
+
+ATF_TC(pow_zero_x);
+ATF_TC_HEAD(pow_zero_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(+-0.0, y) == +-0.0 || HUGE");
+}
+
+ATF_TC_BODY(pow_zero_x, tc)
+{
+ double z;
+
+ /*
+ * If x is +0.0 or -0.0, y > 0, and y
+ * is an odd integer, x is returned.
+ */
+ z = pow(+0.0, 3.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+0.0, 3.0) != +0.0");
+
+ z = pow(-0.0, 3.0);
+
+ if (fabs(z) > 0.0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("pow(-0.0, 3.0) != -0.0");
+
+ /*
+ * If y > 0 and not an odd integer,
+ * if x is +0.0 or -0.0, +0.0 is returned.
+ */
+ z = pow(+0.0, 4.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(+0.0, 4.0) != +0.0");
+
+ z = pow(-0.0, 4.0);
+
+ if (fabs(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("pow(-0.0, 4.0) != +0.0");
+
+ /*
+ * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
+ * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
+ */
+ z = pow(+0.0, -4.0);
+
+ if (z != HUGE_VAL) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("pow(+0.0, -4.0) != HUGE_VAL");
+ }
+
+ z = pow(-0.0, -4.0);
+
+ if (z != HUGE_VAL) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("pow(-0.0, -4.0) != HUGE_VAL");
+ }
+
+ z = pow(+0.0, -5.0);
+
+ if (z != HUGE_VAL) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("pow(+0.0, -5.0) != HUGE_VAL");
+ }
+
+ z = pow(-0.0, -5.0);
+
+ if (z != -HUGE_VAL)
+ atf_tc_fail_nonfatal("pow(-0.0, -5.0) != -HUGE_VAL");
+}
+
+ATF_TC(pow_zero_y);
+ATF_TC_HEAD(pow_zero_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test pow(x, +-0.0) == 1.0");
+}
+
+ATF_TC_BODY(pow_zero_y, tc)
+{
+ const double x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
+ const double z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of x (including NaN),
+ * if y is +0.0 or -0.0, 1.0 is returned.
+ */
+ if (pow(z, +0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(NaN, +0.0) != 1.0");
+
+ if (pow(z, -0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(NaN, -0.0) != 1.0");
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (pow(x[i], +0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(%0.01f, +0.0) != 1.0", x[i]);
+
+ if (pow(x[i], -0.0) != 1.0)
+ atf_tc_fail_nonfatal("pow(%0.01f, -0.0) != 1.0", x[i]);
+ }
+}
+
+/*
+ * powf(3)
+ */
+ATF_TC(powf_nan_x);
+ATF_TC_HEAD(powf_nan_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(NaN, y) == NaN");
+}
+
+ATF_TC_BODY(powf_nan_x, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnanf(powf(x, 2.0)) != 0);
+}
+
+ATF_TC(powf_nan_y);
+ATF_TC_HEAD(powf_nan_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, NaN) == NaN");
+}
+
+ATF_TC_BODY(powf_nan_y, tc)
+{
+ const float y = 0.0L / 0.0L;
+
+ ATF_CHECK(isnanf(powf(2.0, y)) != 0);
+}
+
+ATF_TC(powf_inf_neg_x);
+ATF_TC_HEAD(powf_inf_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(-Inf, y) == +-Inf || +-0.0");
+}
+
+ATF_TC_BODY(powf_inf_neg_x, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float z;
+
+ /*
+ * If y is odd, y > 0, and x is -Inf, -Inf is returned.
+ * If y is even, y > 0, and x is -Inf, +Inf is returned.
+ */
+ z = powf(x, 3.0);
+
+ if (isinff(z) == 0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("powf(-Inf, 3.0) != -Inf");
+
+ z = powf(x, 4.0);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(-Inf, 4.0) != +Inf");
+
+ /*
+ * If y is odd, y < 0, and x is -Inf, -0.0 is returned.
+ * If y is even, y < 0, and x is -Inf, +0.0 is returned.
+ */
+ z = powf(x, -3.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) == 0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("powf(-Inf, -3.0) != -0.0");
+ }
+
+ z = powf(x, -4.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(-Inf -4.0) != +0.0");
+}
+
+ATF_TC(powf_inf_neg_y);
+ATF_TC_HEAD(powf_inf_neg_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, -Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(powf_inf_neg_y, tc)
+{
+ const float y = -1.0L / 0.0L;
+ float z;
+
+ /*
+ * If |x| < 1 and y is -Inf, +Inf is returned.
+ * If |x| > 1 and y is -Inf, +0.0 is returned.
+ */
+ z = powf(0.1, y);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(0.1, -Inf) != +Inf");
+
+ z = powf(1.1, y);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(1.1, -Inf) != +0.0");
+}
+
+ATF_TC(powf_inf_pos_x);
+ATF_TC_HEAD(powf_inf_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(+Inf, y) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(powf_inf_pos_x, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float z;
+
+ /*
+ * For y < 0, if x is +Inf, +0.0 is returned.
+ * For y > 0, if x is +Inf, +Inf is returned.
+ */
+ z = powf(x, -2.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+Inf, -2.0) != +0.0");
+
+ z = powf(x, 2.0);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+Inf, 2.0) != +Inf");
+}
+
+ATF_TC(powf_inf_pos_y);
+ATF_TC_HEAD(powf_inf_pos_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, +Inf) == +Inf || +0.0");
+}
+
+ATF_TC_BODY(powf_inf_pos_y, tc)
+{
+ const float y = 1.0L / 0.0L;
+ float z;
+
+ /*
+ * If |x| < 1 and y is +Inf, +0.0 is returned.
+ * If |x| > 1 and y is +Inf, +Inf is returned.
+ */
+ z = powf(0.1, y);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(0.1, +Inf) != +0.0");
+
+ z = powf(1.1, y);
+
+ if (isinff(z) == 0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(1.1, +Inf) != +Inf");
+}
+
+ATF_TC(powf_one_neg_x);
+ATF_TC_HEAD(powf_one_neg_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(-1.0, +-Inf) == 1.0");
+}
+
+ATF_TC_BODY(powf_one_neg_x, tc)
+{
+ const float infp = 1.0L / 0.0L;
+ const float infn = -1.0L / 0.0L;
+
+ /*
+ * If x is -1.0, and y is +-Inf, 1.0 shall be returned.
+ */
+ ATF_REQUIRE(isinff(infp) != 0);
+ ATF_REQUIRE(isinff(infn) != 0);
+
+ if (powf(-1.0, infp) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("powf(-1.0, +Inf) != 1.0");
+ }
+
+ if (powf(-1.0, infn) != 1.0) {
+ atf_tc_expect_fail("PR lib/45372");
+ atf_tc_fail_nonfatal("powf(-1.0, -Inf) != 1.0");
+ }
+}
+
+ATF_TC(powf_one_pos_x);
+ATF_TC_HEAD(powf_one_pos_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(1.0, y) == 1.0");
+}
+
+ATF_TC_BODY(powf_one_pos_x, tc)
+{
+ const float y[] = { 0.0, 0.1, 2.0, -3.0, 99.0, 99.99, 9999999.9 };
+ const float z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of y (including NaN),
+ * if x is 1.0, 1.0 shall be returned.
+ */
+ if (powf(1.0, z) != 1.0)
+ atf_tc_fail_nonfatal("powf(1.0, NaN) != 1.0");
+
+ for (i = 0; i < __arraycount(y); i++) {
+
+ if (powf(1.0, y[i]) != 1.0)
+ atf_tc_fail_nonfatal("powf(1.0, %0.01f) != 1.0", y[i]);
+ }
+}
+
+ATF_TC(powf_zero_x);
+ATF_TC_HEAD(powf_zero_x, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(+-0.0, y) == +-0.0 || HUGE");
+}
+
+ATF_TC_BODY(powf_zero_x, tc)
+{
+ float z;
+
+ /*
+ * If x is +0.0 or -0.0, y > 0, and y
+ * is an odd integer, x is returned.
+ */
+ z = powf(+0.0, 3.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+0.0, 3.0) != +0.0");
+
+ z = powf(-0.0, 3.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) == 0)
+ atf_tc_fail_nonfatal("powf(-0.0, 3.0) != -0.0");
+
+ /*
+ * If y > 0 and not an odd integer,
+ * if x is +0.0 or -0.0, +0.0 is returned.
+ */
+ z = powf(+0.0, 4.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(+0.0, 4.0) != +0.0");
+
+ z = powf(-0.0, 4.0);
+
+ if (fabsf(z) > 0.0 || signbit(z) != 0)
+ atf_tc_fail_nonfatal("powf(-0.0, 4.0) != +0.0");
+
+ /*
+ * If y < 0 and x is +0.0 or -0.0, either +-HUGE_VAL,
+ * +-HUGE_VALF, or +-HUGE_VALL shall be returned.
+ */
+ z = powf(+0.0, -4.0);
+
+ if (z != HUGE_VALF) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("powf(+0.0, -4.0) != HUGE_VALF");
+ }
+
+ z = powf(-0.0, -4.0);
+
+ if (z != HUGE_VALF) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("powf(-0.0, -4.0) != HUGE_VALF");
+ }
+
+ z = powf(+0.0, -5.0);
+
+ if (z != HUGE_VALF) {
+ atf_tc_expect_fail("PR port-amd64/45391");
+ atf_tc_fail_nonfatal("powf(+0.0, -5.0) != HUGE_VALF");
+ }
+
+ z = powf(-0.0, -5.0);
+
+ if (z != -HUGE_VALF)
+ atf_tc_fail_nonfatal("powf(-0.0, -5.0) != -HUGE_VALF");
+}
+
+ATF_TC(powf_zero_y);
+ATF_TC_HEAD(powf_zero_y, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test powf(x, +-0.0) == 1.0");
+}
+
+ATF_TC_BODY(powf_zero_y, tc)
+{
+ const float x[] = { 0.1, -3.0, 77.0, 99.99, 101.0000001 };
+ const float z = 0.0L / 0.0L;
+ size_t i;
+
+ /*
+ * For any value of x (including NaN),
+ * if y is +0.0 or -0.0, 1.0 is returned.
+ */
+ if (powf(z, +0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(NaN, +0.0) != 1.0");
+
+ if (powf(z, -0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(NaN, -0.0) != 1.0");
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ if (powf(x[i], +0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(%0.01f, +0.0) != 1.0",x[i]);
+
+ if (powf(x[i], -0.0) != 1.0)
+ atf_tc_fail_nonfatal("powf(%0.01f, -0.0) != 1.0",x[i]);
+ }
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, pow_nan_x);
+ ATF_TP_ADD_TC(tp, pow_nan_y);
+ ATF_TP_ADD_TC(tp, pow_inf_neg_x);
+ ATF_TP_ADD_TC(tp, pow_inf_neg_y);
+ ATF_TP_ADD_TC(tp, pow_inf_pos_x);
+ ATF_TP_ADD_TC(tp, pow_inf_pos_y);
+ ATF_TP_ADD_TC(tp, pow_one_neg_x);
+ ATF_TP_ADD_TC(tp, pow_one_pos_x);
+ ATF_TP_ADD_TC(tp, pow_zero_x);
+ ATF_TP_ADD_TC(tp, pow_zero_y);
+
+ ATF_TP_ADD_TC(tp, powf_nan_x);
+ ATF_TP_ADD_TC(tp, powf_nan_y);
+ ATF_TP_ADD_TC(tp, powf_inf_neg_x);
+ ATF_TP_ADD_TC(tp, powf_inf_neg_y);
+ ATF_TP_ADD_TC(tp, powf_inf_pos_x);
+ ATF_TP_ADD_TC(tp, powf_inf_pos_y);
+ ATF_TP_ADD_TC(tp, powf_one_neg_x);
+ ATF_TP_ADD_TC(tp, powf_one_pos_x);
+ ATF_TP_ADD_TC(tp, powf_zero_x);
+ ATF_TP_ADD_TC(tp, powf_zero_y);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_precision.c b/lib/libm/t_precision.c
new file mode 100644
index 000000000000..390be9dd18aa
--- /dev/null
+++ b/lib/libm/t_precision.c
@@ -0,0 +1,76 @@
+/* $NetBSD: t_precision.c,v 1.1 2013/11/11 11:10:45 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2013 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Joerg Sonnenberger.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_precision.c,v 1.1 2013/11/11 11:10:45 joerg Exp $");
+
+#include <atf-c.h>
+#include <atf-c/config.h>
+
+#include <float.h>
+#include <stdlib.h>
+
+ATF_TC(t_precision);
+
+ATF_TC_HEAD(t_precision, tc)
+{
+ atf_tc_set_md_var(tc, "descr",
+ "Basic precision test for double and long double");
+}
+
+volatile double x = 1;
+volatile long double y = 1;
+
+ATF_TC_BODY(t_precision, tc)
+{
+ x += DBL_EPSILON;
+ ATF_CHECK(x != 1.0);
+ x -= 1;
+ ATF_CHECK(x == DBL_EPSILON);
+
+ x = 2;
+ x += DBL_EPSILON;
+ ATF_CHECK(x == 2.0);
+
+ y += LDBL_EPSILON;
+ ATF_CHECK(y != 1.0L);
+ y -= 1;
+ ATF_CHECK(y == LDBL_EPSILON);
+ y = 2;
+ y += LDBL_EPSILON;
+ ATF_CHECK(y == 2.0L);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+ ATF_TP_ADD_TC(tp, t_precision);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_round.c b/lib/libm/t_round.c
new file mode 100644
index 000000000000..f47e1a0f8a13
--- /dev/null
+++ b/lib/libm/t_round.c
@@ -0,0 +1,85 @@
+/* $NetBSD: t_round.c,v 1.4 2013/11/11 23:57:34 joerg Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <float.h>
+#include <math.h>
+
+/*
+ * This tests for a bug in the initial implementation where
+ * precision was lost in an internal substraction, leading to
+ * rounding into the wrong direction.
+ */
+
+/* 0.5 - EPSILON */
+#define VAL 0x0.7ffffffffffffcp0
+#define VALF 0x0.7fffff8p0
+#define VALL (0.5 - LDBL_EPSILON)
+
+#ifdef __vax__
+#define SMALL_NUM 1.0e-38
+#else
+#define SMALL_NUM 1.0e-40
+#endif
+
+ATF_TC(round_dir);
+ATF_TC_HEAD(round_dir, tc)
+{
+ atf_tc_set_md_var(tc, "descr","Check for rounding in wrong direction");
+}
+
+ATF_TC_BODY(round_dir, tc)
+{
+ double a = VAL, b, c;
+ float af = VALF, bf, cf;
+ long double al = VALL, bl, cl;
+
+ b = round(a);
+ bf = roundf(af);
+ bl = roundl(al);
+
+ ATF_CHECK(fabs(b) < SMALL_NUM);
+ ATF_CHECK(fabsf(bf) < SMALL_NUM);
+ ATF_CHECK(fabsl(bl) < SMALL_NUM);
+
+ c = round(-a);
+ cf = roundf(-af);
+ cl = roundl(-al);
+
+ ATF_CHECK(fabs(c) < SMALL_NUM);
+ ATF_CHECK(fabsf(cf) < SMALL_NUM);
+ ATF_CHECK(fabsl(cl) < SMALL_NUM);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, round_dir);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_scalbn.c b/lib/libm/t_scalbn.c
new file mode 100644
index 000000000000..586c2c3bc621
--- /dev/null
+++ b/lib/libm/t_scalbn.c
@@ -0,0 +1,523 @@
+/* $NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_scalbn.c,v 1.11 2014/03/03 10:39:08 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)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(NaN, n) == NaN");
+}
+
+ATF_TC_BODY(scalbn_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(scalbn_inf_neg);
+ATF_TC_HEAD(scalbn_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(-Inf, n) == -Inf");
+}
+
+ATF_TC_BODY(scalbn_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbn(x, exps[i]) == x);
+}
+
+ATF_TC(scalbn_inf_pos);
+ATF_TC_HEAD(scalbn_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(+Inf, n) == +Inf");
+}
+
+ATF_TC_BODY(scalbn_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbn(x, exps[i]) == x);
+}
+
+ATF_TC(scalbn_ldexp);
+ATF_TC_HEAD(scalbn_ldexp, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(x, n) == ldexp(x, n)");
+}
+
+ATF_TC_BODY(scalbn_ldexp, tc)
+{
+#if FLT_RADIX == 2
+ const double x = 2.91288191221812821;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(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
+}
+
+ATF_TC(scalbn_zero_neg);
+ATF_TC_HEAD(scalbn_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(-0.0, n) == -0.0");
+}
+
+ATF_TC_BODY(scalbn_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(scalbn_zero_pos);
+ATF_TC_HEAD(scalbn_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbn(+0.0, n) == +0.0");
+}
+
+ATF_TC_BODY(scalbn_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbn(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+/*
+ * 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)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(NaN, n) == NaN");
+}
+
+ATF_TC_BODY(scalbnf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(isnan(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+}
+
+ATF_TC(scalbnf_inf_neg);
+ATF_TC_HEAD(scalbnf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(-Inf, n) == -Inf");
+}
+
+ATF_TC_BODY(scalbnf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnf(x, exps[i]) == x);
+}
+
+ATF_TC(scalbnf_inf_pos);
+ATF_TC_HEAD(scalbnf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(+Inf, n) == +Inf");
+}
+
+ATF_TC_BODY(scalbnf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnf(x, exps[i]) == x);
+}
+
+ATF_TC(scalbnf_ldexpf);
+ATF_TC_HEAD(scalbnf_ldexpf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(x, n) == ldexpf(x, n)");
+}
+
+ATF_TC_BODY(scalbnf_ldexpf, tc)
+{
+#if FLT_RADIX == 2
+ const float x = 2.91288191221812821;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(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
+}
+
+ATF_TC(scalbnf_zero_neg);
+ATF_TC_HEAD(scalbnf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(-0.0, n) == -0.0");
+}
+
+ATF_TC_BODY(scalbnf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+}
+
+ATF_TC(scalbnf_zero_pos);
+ATF_TC_HEAD(scalbnf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnf(+0.0, n) == +0.0");
+}
+
+ATF_TC_BODY(scalbnf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnf(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+}
+
+/*
+ * 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)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(NaN, n) == NaN");
+}
+
+ATF_TC_BODY(scalbnl_nan, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = 0.0L / 0.0L;
+ long double y;
+ size_t i;
+
+ if (isnan(x) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("(0.0L / 0.0L) != NaN");
+ }
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnl(x, exps[i]);
+ ATF_CHECK(isnan(y) != 0);
+ }
+#endif
+}
+
+ATF_TC(scalbnl_inf_neg);
+ATF_TC_HEAD(scalbnl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(-Inf, n) == -Inf");
+}
+
+ATF_TC_BODY(scalbnl_inf_neg, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = -1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnl(x, exps[i]) == x);
+#endif
+}
+
+ATF_TC(scalbnl_inf_pos);
+ATF_TC_HEAD(scalbnl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(+Inf, n) == +Inf");
+}
+
+ATF_TC_BODY(scalbnl_inf_pos, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = 1.0L / 0.0L;
+ size_t i;
+
+ for (i = 0; i < __arraycount(exps); i++)
+ ATF_CHECK(scalbnl(x, exps[i]) == x);
+#endif
+}
+
+ATF_TC(scalbnl_zero_neg);
+ATF_TC_HEAD(scalbnl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(-0.0, n) == -0.0");
+}
+
+ATF_TC_BODY(scalbnl_zero_neg, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = -0.0L;
+ long double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) != 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnl(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) != 0);
+ }
+#endif
+}
+
+ATF_TC(scalbnl_zero_pos);
+ATF_TC_HEAD(scalbnl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test scalbnl(+0.0, n) == +0.0");
+}
+
+ATF_TC_BODY(scalbnl_zero_pos, tc)
+{
+#ifndef __HAVE_LONG_DOUBLE
+ atf_tc_skip("Requires long double support");
+#else
+ const long double x = 0.0L;
+ long double y;
+ size_t i;
+
+ ATF_REQUIRE(signbit(x) == 0);
+
+ for (i = 0; i < __arraycount(exps); i++) {
+ y = scalbnl(x, exps[i]);
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(y) == 0);
+ }
+#endif
+}
+
+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);
+ ATF_TP_ADD_TC(tp, scalbn_ldexp);
+ 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);
+ ATF_TP_ADD_TC(tp, scalbnf_ldexpf);
+ 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);
+/* ATF_TP_ADD_TC(tp, scalbnl_ldexp); */
+ ATF_TP_ADD_TC(tp, scalbnl_zero_neg);
+ ATF_TP_ADD_TC(tp, scalbnl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_sin.c b/lib/libm/t_sin.c
new file mode 100644
index 000000000000..a82f49dc65d6
--- /dev/null
+++ b/lib/libm/t_sin.c
@@ -0,0 +1,263 @@
+/* $NetBSD: t_sin.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+
+static const struct {
+ int angle;
+ double x;
+ double y;
+} angles[] = {
+ { -180, -3.141592653589793, 0.0000000000000000 },
+ { -135, -2.356194490192345, -0.7071067811865476 },
+ { -90, -1.570796326794897, -1.0000000000000000 },
+ { -45, -0.785398163397448, -0.7071067811865476 },
+ { 0, 0.000000000000000, 0.0000000000000000 },
+ { 30, 0.523598775598299, 0.5000000000000000 },
+ { 45, 0.785398163397448, 0.7071067811865476 },
+ { 60, 1.047197551196598, 0.8660254037844386 },
+ { 90, 1.570796326794897, 1.0000000000000000 },
+ { 120, 2.094395102393195, 0.8660254037844386 },
+ { 135, 2.356194490192345, 0.7071067811865476 },
+ { 150, 2.617993877991494, 0.5000000000000000 },
+ { 180, 3.141592653589793, 0.0000000000000000 },
+ { 270, 4.712388980384690, -1.0000000000000000 },
+ { 360, 6.283185307179586, 0.0000000000000000 }
+};
+
+/*
+ * sin(3)
+ */
+ATF_TC(sin_angles);
+ATF_TC_HEAD(sin_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(sin_angles, tc)
+{
+ const double eps = 1.0e-15;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ if (fabs(sin(angles[i].x) - angles[i].y) > eps)
+ atf_tc_fail_nonfatal("sin(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(sin_nan);
+ATF_TC_HEAD(sin_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(NaN) == NaN");
+}
+
+ATF_TC_BODY(sin_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sin(x)) != 0);
+}
+
+ATF_TC(sin_inf_neg);
+ATF_TC_HEAD(sin_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sin_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(isnan(sin(x)) != 0);
+}
+
+ATF_TC(sin_inf_pos);
+ATF_TC_HEAD(sin_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(+Inf) == NaN");
+}
+
+ATF_TC_BODY(sin_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(isnan(sin(x)) != 0);
+}
+
+
+ATF_TC(sin_zero_neg);
+ATF_TC_HEAD(sin_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sin_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(sin(x) == x);
+}
+
+ATF_TC(sin_zero_pos);
+ATF_TC_HEAD(sin_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sin(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sin_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(sin(x) == x);
+}
+
+/*
+ * sinf(3)
+ */
+ATF_TC(sinf_angles);
+ATF_TC_HEAD(sinf_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(sinf_angles, tc)
+{
+ const float eps = 1.0e-6;
+ float x, y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ x = angles[i].x;
+ y = angles[i].y;
+
+ if (fabsf(sinf(x) - y) > eps)
+ atf_tc_fail_nonfatal("sinf(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(sinf_nan);
+ATF_TC_HEAD(sinf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(NaN) == NaN");
+}
+
+ATF_TC_BODY(sinf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sinf(x)) != 0);
+}
+
+ATF_TC(sinf_inf_neg);
+ATF_TC_HEAD(sinf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sinf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(sinf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("sinf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(sinf_inf_pos);
+ATF_TC_HEAD(sinf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(sinf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(sinf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("sinf(+Inf) != NaN");
+ }
+}
+
+
+ATF_TC(sinf_zero_neg);
+ATF_TC_HEAD(sinf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sinf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(sinf(x) == x);
+}
+
+ATF_TC(sinf_zero_pos);
+ATF_TC_HEAD(sinf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sinf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(sinf(x) == x);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sin_angles);
+ ATF_TP_ADD_TC(tp, sin_nan);
+ ATF_TP_ADD_TC(tp, sin_inf_neg);
+ ATF_TP_ADD_TC(tp, sin_inf_pos);
+ ATF_TP_ADD_TC(tp, sin_zero_neg);
+ ATF_TP_ADD_TC(tp, sin_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sinf_angles);
+ ATF_TP_ADD_TC(tp, sinf_nan);
+ ATF_TP_ADD_TC(tp, sinf_inf_neg);
+ ATF_TP_ADD_TC(tp, sinf_inf_pos);
+ ATF_TP_ADD_TC(tp, sinf_zero_neg);
+ ATF_TP_ADD_TC(tp, sinf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_sinh.c b/lib/libm/t_sinh.c
new file mode 100644
index 000000000000..d935f0ea7ffb
--- /dev/null
+++ b/lib/libm/t_sinh.c
@@ -0,0 +1,273 @@
+/* $NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <stdio.h>
+
+static const struct {
+ double x;
+ double y;
+ double e;
+} values[] = {
+ { -10, -11013.23287470339, 1e4, },
+ { -2, -3.626860407847019, 1, },
+ { -1, -1.175201193643801, 1, },
+ { -0.05, -0.050020835937655, 1, },
+ { -0.001,-0.001000000166667, 1, },
+ { 0.001, 0.001000000166667, 1, },
+ { 0.05, 0.050020835937655, 1, },
+ { 1, 1.175201193643801, 1, },
+ { 2, 3.626860407847019, 1, },
+ { 10, 11013.23287470339, 1e4, },
+};
+
+/*
+ * sinh(3)
+ */
+ATF_TC(sinh_inrange);
+ATF_TC_HEAD(sinh_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sinh(x) for some values");
+}
+
+ATF_TC_BODY(sinh_inrange, tc)
+{
+ double eps;
+ double x;
+ double y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-15 * values[i].e;
+
+ if (fabs(sinh(x) - y) > eps)
+ atf_tc_fail_nonfatal("sinh(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(sinh_nan);
+ATF_TC_HEAD(sinh_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(NaN) == NaN");
+}
+
+ATF_TC_BODY(sinh_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sinh(x)) != 0);
+}
+
+ATF_TC(sinh_inf_neg);
+ATF_TC_HEAD(sinh_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(sinh_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = sinh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(sinh_inf_pos);
+ATF_TC_HEAD(sinh_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sinh_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = sinh(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sinh_zero_neg);
+ATF_TC_HEAD(sinh_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sinh_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = sinh(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sinh(-0.0) != -0.0");
+}
+
+ATF_TC(sinh_zero_pos);
+ATF_TC_HEAD(sinh_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinh(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sinh_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = sinh(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sinh(+0.0) != +0.0");
+}
+
+/*
+ * sinhf(3)
+ */
+ATF_TC(sinhf_inrange);
+ATF_TC_HEAD(sinhf_inrange, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "sinhf(x) for some values");
+}
+
+ATF_TC_BODY(sinhf_inrange, tc)
+{
+ float eps;
+ float x;
+ float y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(values); i++) {
+ x = values[i].x;
+ y = values[i].y;
+ eps = 1e-6 * values[i].e;
+
+ if (fabsf(sinhf(x) - y) > eps)
+ atf_tc_fail_nonfatal("sinhf(%g) != %g\n", x, y);
+ }
+}
+
+ATF_TC(sinhf_nan);
+ATF_TC_HEAD(sinhf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(NaN) == NaN");
+}
+
+ATF_TC_BODY(sinhf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sinhf(x)) != 0);
+}
+
+ATF_TC(sinhf_inf_neg);
+ATF_TC_HEAD(sinhf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(-Inf) == -Inf");
+}
+
+ATF_TC_BODY(sinhf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = sinhf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) != 0);
+}
+
+ATF_TC(sinhf_inf_pos);
+ATF_TC_HEAD(sinhf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sinhf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = sinhf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sinhf_zero_neg);
+ATF_TC_HEAD(sinhf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sinhf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = sinhf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sinhf(-0.0) != -0.0");
+}
+
+ATF_TC(sinhf_zero_pos);
+ATF_TC_HEAD(sinhf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sinhf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sinhf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = sinhf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sinhf(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sinh_inrange);
+ ATF_TP_ADD_TC(tp, sinh_nan);
+ ATF_TP_ADD_TC(tp, sinh_inf_neg);
+ ATF_TP_ADD_TC(tp, sinh_inf_pos);
+ ATF_TP_ADD_TC(tp, sinh_zero_neg);
+ ATF_TP_ADD_TC(tp, sinh_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sinhf_inrange);
+ ATF_TP_ADD_TC(tp, sinhf_nan);
+ ATF_TP_ADD_TC(tp, sinhf_inf_neg);
+ ATF_TP_ADD_TC(tp, sinhf_inf_pos);
+ ATF_TP_ADD_TC(tp, sinhf_zero_neg);
+ ATF_TP_ADD_TC(tp, sinhf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_sqrt.c b/lib/libm/t_sqrt.c
new file mode 100644
index 000000000000..1d551ec3101d
--- /dev/null
+++ b/lib/libm/t_sqrt.c
@@ -0,0 +1,368 @@
+/* $NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+#include <float.h>
+#include <stdio.h>
+
+/*
+ * sqrt(3)
+ */
+ATF_TC(sqrt_nan);
+ATF_TC_HEAD(sqrt_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(NaN) == NaN");
+}
+
+ATF_TC_BODY(sqrt_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sqrt(x)) != 0);
+}
+
+ATF_TC(sqrt_pow);
+ATF_TC_HEAD(sqrt_pow, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(3) vs. pow(3)");
+}
+
+ATF_TC_BODY(sqrt_pow, tc)
+{
+ const double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
+#if __DBL_MIN_10_EXP__ <= -40
+ const double eps = 1.0e-40;
+#else
+ const double eps = __DBL_MIN__*4.0;
+#endif
+ double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = sqrt(x[i]);
+ z = pow(x[i], 1.0 / 2.0);
+
+ if (fabs(y - z) > eps)
+ atf_tc_fail_nonfatal("sqrt(%0.03f) != "
+ "pow(%0.03f, 1/2)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(sqrt_inf_neg);
+ATF_TC_HEAD(sqrt_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sqrt_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+ double y = sqrt(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(sqrt_inf_pos);
+ATF_TC_HEAD(sqrt_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sqrt_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+ double y = sqrt(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sqrt_zero_neg);
+ATF_TC_HEAD(sqrt_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sqrt_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = sqrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sqrt(-0.0) != -0.0");
+}
+
+ATF_TC(sqrt_zero_pos);
+ATF_TC_HEAD(sqrt_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrt(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sqrt_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = sqrt(x);
+
+ if (fabs(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sqrt(+0.0) != +0.0");
+}
+
+/*
+ * sqrtf(3)
+ */
+ATF_TC(sqrtf_nan);
+ATF_TC_HEAD(sqrtf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(NaN) == NaN");
+}
+
+ATF_TC_BODY(sqrtf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sqrtf(x)) != 0);
+}
+
+ATF_TC(sqrtf_powf);
+ATF_TC_HEAD(sqrtf_powf, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(3) vs. powf(3)");
+}
+
+ATF_TC_BODY(sqrtf_powf, tc)
+{
+ const float x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
+ const float eps = 1.0e-30;
+ volatile float y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = sqrtf(x[i]);
+ z = powf(x[i], 1.0 / 2.0);
+
+ if (fabsf(y - z) > eps)
+ atf_tc_fail_nonfatal("sqrtf(%0.03f) != "
+ "powf(%0.03f, 1/2)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(sqrtf_inf_neg);
+ATF_TC_HEAD(sqrtf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sqrtf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+ float y = sqrtf(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(sqrtf_inf_pos);
+ATF_TC_HEAD(sqrtf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sqrtf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+ float y = sqrtf(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sqrtf_zero_neg);
+ATF_TC_HEAD(sqrtf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sqrtf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = sqrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sqrtf(-0.0) != -0.0");
+}
+
+ATF_TC(sqrtf_zero_pos);
+ATF_TC_HEAD(sqrtf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sqrtf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = sqrtf(x);
+
+ if (fabsf(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sqrtf(+0.0) != +0.0");
+}
+
+/*
+ * sqrtl(3)
+ */
+ATF_TC(sqrtl_nan);
+ATF_TC_HEAD(sqrtl_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(NaN) == NaN");
+}
+
+ATF_TC_BODY(sqrtl_nan, tc)
+{
+ const long double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(sqrtl(x)) != 0);
+}
+
+ATF_TC(sqrtl_powl);
+ATF_TC_HEAD(sqrtl_powl, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(3) vs. powl(3)");
+}
+
+ATF_TC_BODY(sqrtl_powl, tc)
+{
+ const long double x[] = { 0.0, 0.005, 1.0, 99.0, 123.123, 9999.9999 };
+ const long double eps = 5.0*DBL_EPSILON; /* XXX powl == pow for now */
+ volatile long double y, z;
+ size_t i;
+
+ for (i = 0; i < __arraycount(x); i++) {
+
+ y = sqrtl(x[i]);
+ z = powl(x[i], 1.0 / 2.0);
+
+ if (fabsl(y - z) > eps)
+ atf_tc_fail_nonfatal("sqrtl(%0.03Lf) != "
+ "powl(%0.03Lf, 1/2)\n", x[i], x[i]);
+ }
+}
+
+ATF_TC(sqrtl_inf_neg);
+ATF_TC_HEAD(sqrtl_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(-Inf) == NaN");
+}
+
+ATF_TC_BODY(sqrtl_inf_neg, tc)
+{
+ const long double x = -1.0L / 0.0L;
+ long double y = sqrtl(x);
+
+ ATF_CHECK(isnan(y) != 0);
+}
+
+ATF_TC(sqrtl_inf_pos);
+ATF_TC_HEAD(sqrtl_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(+Inf) == +Inf");
+}
+
+ATF_TC_BODY(sqrtl_inf_pos, tc)
+{
+ const long double x = 1.0L / 0.0L;
+ long double y = sqrtl(x);
+
+ ATF_CHECK(isinf(y) != 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TC(sqrtl_zero_neg);
+ATF_TC_HEAD(sqrtl_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(sqrtl_zero_neg, tc)
+{
+ const long double x = -0.0L;
+ long double y = sqrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) == 0)
+ atf_tc_fail_nonfatal("sqrtl(-0.0) != -0.0");
+}
+
+ATF_TC(sqrtl_zero_pos);
+ATF_TC_HEAD(sqrtl_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test sqrtl(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(sqrtl_zero_pos, tc)
+{
+ const long double x = 0.0L;
+ long double y = sqrtl(x);
+
+ if (fabsl(y) > 0.0 || signbit(y) != 0)
+ atf_tc_fail_nonfatal("sqrtl(+0.0) != +0.0");
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, sqrt_nan);
+ ATF_TP_ADD_TC(tp, sqrt_pow);
+ ATF_TP_ADD_TC(tp, sqrt_inf_neg);
+ ATF_TP_ADD_TC(tp, sqrt_inf_pos);
+ ATF_TP_ADD_TC(tp, sqrt_zero_neg);
+ ATF_TP_ADD_TC(tp, sqrt_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sqrtf_nan);
+ ATF_TP_ADD_TC(tp, sqrtf_powf);
+ ATF_TP_ADD_TC(tp, sqrtf_inf_neg);
+ ATF_TP_ADD_TC(tp, sqrtf_inf_pos);
+ ATF_TP_ADD_TC(tp, sqrtf_zero_neg);
+ ATF_TP_ADD_TC(tp, sqrtf_zero_pos);
+
+ ATF_TP_ADD_TC(tp, sqrtl_nan);
+ ATF_TP_ADD_TC(tp, sqrtl_powl);
+ ATF_TP_ADD_TC(tp, sqrtl_inf_neg);
+ ATF_TP_ADD_TC(tp, sqrtl_inf_pos);
+ ATF_TP_ADD_TC(tp, sqrtl_zero_neg);
+ ATF_TP_ADD_TC(tp, sqrtl_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_tan.c b/lib/libm/t_tan.c
new file mode 100644
index 000000000000..807e3d1f3364
--- /dev/null
+++ b/lib/libm/t_tan.c
@@ -0,0 +1,260 @@
+/* $NetBSD: t_tan.c,v 1.5 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <atf-c.h>
+#include <math.h>
+
+static const struct {
+ int angle;
+ double x;
+ double y;
+} angles[] = {
+ { -180, -3.141592653589793, 0.0000000000000000 },
+ { -135, -2.356194490192345, 1.0000000000000000 },
+ { -45, -0.785398163397448, -1.0000000000000000 },
+ { 0, 0.000000000000000, 0.0000000000000000 },
+ { 30, 0.523598775598299, 0.5773502691896258 },
+ { 45, 0.785398163397448, 1.0000000000000000 },
+ { 60, 1.047197551196598, 1.7320508075688773 },
+ { 120, 2.094395102393195, -1.7320508075688773 },
+ { 135, 2.356194490192345, -1.0000000000000000 },
+ { 150, 2.617993877991494, -0.5773502691896258 },
+ { 180, 3.141592653589793, 0.0000000000000000 },
+ { 360, 6.283185307179586, 0.0000000000000000 }
+};
+
+/*
+ * tan(3)
+ */
+ATF_TC(tan_angles);
+ATF_TC_HEAD(tan_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(tan_angles, tc)
+{
+ const double eps = 1.0e-14;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ if (fabs(tan(angles[i].x) - angles[i].y) > eps)
+ atf_tc_fail_nonfatal("tan(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(tan_nan);
+ATF_TC_HEAD(tan_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(NaN) == NaN");
+}
+
+ATF_TC_BODY(tan_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tan(x)) != 0);
+}
+
+ATF_TC(tan_inf_neg);
+ATF_TC_HEAD(tan_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(-Inf) == NaN");
+}
+
+ATF_TC_BODY(tan_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(isnan(tan(x)) != 0);
+}
+
+ATF_TC(tan_inf_pos);
+ATF_TC_HEAD(tan_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(+Inf) == NaN");
+}
+
+ATF_TC_BODY(tan_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(isnan(tan(x)) != 0);
+}
+
+
+ATF_TC(tan_zero_neg);
+ATF_TC_HEAD(tan_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tan_zero_neg, tc)
+{
+ const double x = -0.0L;
+
+ ATF_CHECK(tan(x) == x);
+}
+
+ATF_TC(tan_zero_pos);
+ATF_TC_HEAD(tan_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tan(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tan_zero_pos, tc)
+{
+ const double x = 0.0L;
+
+ ATF_CHECK(tan(x) == x);
+}
+
+/*
+ * tanf(3)
+ */
+ATF_TC(tanf_angles);
+ATF_TC_HEAD(tanf_angles, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test some selected angles");
+}
+
+ATF_TC_BODY(tanf_angles, tc)
+{
+ const float eps = 1.0e-6;
+ float x, y;
+ size_t i;
+
+ for (i = 0; i < __arraycount(angles); i++) {
+
+ x = angles[i].x;
+ y = angles[i].y;
+
+ if (fabsf(tanf(x) - y) > eps)
+ atf_tc_fail_nonfatal("tanf(%d deg) != %0.01f",
+ angles[i].angle, angles[i].y);
+ }
+}
+
+ATF_TC(tanf_nan);
+ATF_TC_HEAD(tanf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(NaN) == NaN");
+}
+
+ATF_TC_BODY(tanf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tanf(x)) != 0);
+}
+
+ATF_TC(tanf_inf_neg);
+ATF_TC_HEAD(tanf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(-Inf) == NaN");
+}
+
+ATF_TC_BODY(tanf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ if (isnan(tanf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("tanf(-Inf) != NaN");
+ }
+}
+
+ATF_TC(tanf_inf_pos);
+ATF_TC_HEAD(tanf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(+Inf) == NaN");
+}
+
+ATF_TC_BODY(tanf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ if (isnan(tanf(x)) == 0) {
+ atf_tc_expect_fail("PR lib/45362");
+ atf_tc_fail("tanf(+Inf) != NaN");
+ }
+}
+
+
+ATF_TC(tanf_zero_neg);
+ATF_TC_HEAD(tanf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tanf_zero_neg, tc)
+{
+ const float x = -0.0L;
+
+ ATF_CHECK(tanf(x) == x);
+}
+
+ATF_TC(tanf_zero_pos);
+ATF_TC_HEAD(tanf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tanf_zero_pos, tc)
+{
+ const float x = 0.0L;
+
+ ATF_CHECK(tanf(x) == x);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tan_angles);
+ ATF_TP_ADD_TC(tp, tan_nan);
+ ATF_TP_ADD_TC(tp, tan_inf_neg);
+ ATF_TP_ADD_TC(tp, tan_inf_pos);
+ ATF_TP_ADD_TC(tp, tan_zero_neg);
+ ATF_TP_ADD_TC(tp, tan_zero_pos);
+
+ ATF_TP_ADD_TC(tp, tanf_angles);
+ ATF_TP_ADD_TC(tp, tanf_nan);
+ ATF_TP_ADD_TC(tp, tanf_inf_neg);
+ ATF_TP_ADD_TC(tp, tanf_inf_pos);
+ ATF_TP_ADD_TC(tp, tanf_zero_neg);
+ ATF_TP_ADD_TC(tp, tanf_zero_pos);
+
+ return atf_no_error();
+}
diff --git a/lib/libm/t_tanh.c b/lib/libm/t_tanh.c
new file mode 100644
index 000000000000..4cc4551b842c
--- /dev/null
+++ b/lib/libm/t_tanh.c
@@ -0,0 +1,207 @@
+/* $NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Jukka Ruohonen.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: t_tanh.c,v 1.7 2014/03/03 10:39:08 martin Exp $");
+
+#include <atf-c.h>
+#include <math.h>
+
+/*
+ * tanh(3)
+ */
+ATF_TC(tanh_nan);
+ATF_TC_HEAD(tanh_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(NaN) == NaN");
+}
+
+ATF_TC_BODY(tanh_nan, tc)
+{
+ const double x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tanh(x)) != 0);
+}
+
+ATF_TC(tanh_inf_neg);
+ATF_TC_HEAD(tanh_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(tanh_inf_neg, tc)
+{
+ const double x = -1.0L / 0.0L;
+
+ ATF_CHECK(tanh(x) == -1.0);
+}
+
+ATF_TC(tanh_inf_pos);
+ATF_TC_HEAD(tanh_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(+Inf) == +1.0");
+}
+
+ATF_TC_BODY(tanh_inf_pos, tc)
+{
+ const double x = 1.0L / 0.0L;
+
+ ATF_CHECK(tanh(x) == 1.0);
+}
+
+ATF_TC(tanh_zero_neg);
+ATF_TC_HEAD(tanh_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tanh_zero_neg, tc)
+{
+ const double x = -0.0L;
+ double y = tanh(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) != 0);
+
+ ATF_REQUIRE_MSG(signbit(y) != 0,
+ "compiler bug, waiting for newer gcc import, see PR lib/44057");
+}
+
+ATF_TC(tanh_zero_pos);
+ATF_TC_HEAD(tanh_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanh(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tanh_zero_pos, tc)
+{
+ const double x = 0.0L;
+ double y = tanh(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+/*
+ * tanhf(3)
+ */
+ATF_TC(tanhf_nan);
+ATF_TC_HEAD(tanhf_nan, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(NaN) == NaN");
+}
+
+ATF_TC_BODY(tanhf_nan, tc)
+{
+ const float x = 0.0L / 0.0L;
+
+ ATF_CHECK(isnan(x) != 0);
+ ATF_CHECK(isnan(tanhf(x)) != 0);
+}
+
+ATF_TC(tanhf_inf_neg);
+ATF_TC_HEAD(tanhf_inf_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(-Inf) == -1.0");
+}
+
+ATF_TC_BODY(tanhf_inf_neg, tc)
+{
+ const float x = -1.0L / 0.0L;
+
+ ATF_CHECK(tanhf(x) == -1.0);
+}
+
+ATF_TC(tanhf_inf_pos);
+ATF_TC_HEAD(tanhf_inf_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(+Inf) == +1.0");
+}
+
+ATF_TC_BODY(tanhf_inf_pos, tc)
+{
+ const float x = 1.0L / 0.0L;
+
+ ATF_CHECK(tanhf(x) == 1.0);
+}
+
+ATF_TC(tanhf_zero_neg);
+ATF_TC_HEAD(tanhf_zero_neg, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(-0.0) == -0.0");
+}
+
+ATF_TC_BODY(tanhf_zero_neg, tc)
+{
+ const float x = -0.0L;
+ float y = tanh(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) != 0);
+
+ ATF_REQUIRE_MSG(signbit(y) != 0,
+ "compiler bug, waiting for newer gcc import, see PR lib/44057");
+}
+
+ATF_TC(tanhf_zero_pos);
+ATF_TC_HEAD(tanhf_zero_pos, tc)
+{
+ atf_tc_set_md_var(tc, "descr", "Test tanhf(+0.0) == +0.0");
+}
+
+ATF_TC_BODY(tanhf_zero_pos, tc)
+{
+ const float x = 0.0L;
+ float y = tanhf(x);
+
+ ATF_CHECK(x == y);
+ ATF_CHECK(signbit(x) == 0);
+ ATF_CHECK(signbit(y) == 0);
+}
+
+ATF_TP_ADD_TCS(tp)
+{
+
+ ATF_TP_ADD_TC(tp, tanh_nan);
+ ATF_TP_ADD_TC(tp, tanh_inf_neg);
+ ATF_TP_ADD_TC(tp, tanh_inf_pos);
+ ATF_TP_ADD_TC(tp, tanh_zero_neg);
+ ATF_TP_ADD_TC(tp, tanh_zero_pos);
+
+ ATF_TP_ADD_TC(tp, tanhf_nan);
+ ATF_TP_ADD_TC(tp, tanhf_inf_neg);
+ ATF_TP_ADD_TC(tp, tanhf_inf_pos);
+ ATF_TP_ADD_TC(tp, tanhf_zero_neg);
+ ATF_TP_ADD_TC(tp, tanhf_zero_pos);
+
+ return atf_no_error();
+}