diff --git a/contrib/netbsd-tests/lib/libm/t_acos.c b/contrib/netbsd-tests/lib/libm/t_acos.c index f051fb64df42..973f0245cdab 100644 --- a/contrib/netbsd-tests/lib/libm/t_acos.c +++ b/contrib/netbsd-tests/lib/libm/t_acos.c @@ -1,105 +1,105 @@ -/* $NetBSD: t_acos.c,v 1.10 2014/03/05 20:14:46 dsl Exp $ */ +/* $NetBSD: t_acos.c,v 1.11 2018/11/07 03:59:36 riastradh 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 #include #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, }, + { 0.99, 0.1415394733244273, }, }; 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/contrib/netbsd-tests/lib/libm/t_asin.c b/contrib/netbsd-tests/lib/libm/t_asin.c index 06de85216429..213b1f875439 100644 --- a/contrib/netbsd-tests/lib/libm/t_asin.c +++ b/contrib/netbsd-tests/lib/libm/t_asin.c @@ -1,296 +1,307 @@ -/* $NetBSD: t_asin.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_asin.c,v 1.4 2018/11/07 03:59:36 riastradh 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 +#include #include 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; + const double eps = DBL_EPSILON; size_t i; for (i = 0; i < __arraycount(values); i++) { - y = asin(values[i].x); - if (fabs(y - values[i].y) > eps) + double x = values[i].x; + double y = values[i].y; + + if (!(fabs((asin(x) - y)/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; + const float eps = FLT_EPSILON; 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); + float x = values[i].x; + float y = values[i].y; + +#ifdef __NetBSD__ + if (fabs(x) == 0.5) + atf_tc_expect_fail("asinf is busted," + " gives ~2ulp error"); +#endif + if (!(fabsf((asinf(x) - y)/y) <= eps)) { + atf_tc_fail_nonfatal("asinf(%.8g) = %.8g != %.8g," + " error=~%.1fulp", + x, asinf(x), y, fabsf(((asinf(x) - y)/y)/eps)); + } + if (fabs(x) == 0.5) + atf_tc_expect_pass(); } } 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/contrib/netbsd-tests/lib/libm/t_bit.c b/contrib/netbsd-tests/lib/libm/t_bit.c new file mode 100644 index 000000000000..b6e0218f601c --- /dev/null +++ b/contrib/netbsd-tests/lib/libm/t_bit.c @@ -0,0 +1,102 @@ +/* $NetBSD: t_bit.c,v 1.1 2019/04/26 08:52:16 maya Exp $ */ + +/* + * Written by Maya Rashish + * Public domain. + * + * Testing signbit{,f,l} function correctly + */ + +#include +#include +#include +#include +#include +#include + +static const struct { + double input; + bool is_negative; +} values[] = { + { -1, true}, + { -123, true}, + { -123E6, true}, +#ifdef INFINITY + { -INFINITY, true}, + { INFINITY, false}, +#endif + { 123E6, false}, + { 0, false}, + { -FLT_MIN, true}, + { FLT_MIN, false}, + /* + * Cannot be accurately represented as float, + * but sign should be preserved + */ + { DBL_MAX, false}, + { -DBL_MAX, true}, +}; + +#ifdef __HAVE_LONG_DOUBLE +static const struct { + long double input; + bool is_negative; +} ldbl_values[] = { + { -LDBL_MIN, true}, + { LDBL_MIN, false}, + { LDBL_MAX, false}, + { -LDBL_MAX, true}, +}; +#endif + +ATF_TC(signbit); +ATF_TC_HEAD(signbit, tc) +{ + atf_tc_set_md_var(tc, "descr","Check that signbit functions correctly"); +} + +ATF_TC_BODY(signbit, tc) +{ + double iterator_d; + float iterator_f; + + for (unsigned int i = 0; i < __arraycount(values); i++) { + iterator_d = values[i].input; + iterator_f = (float) values[i].input; + if (signbit(iterator_f) != values[i].is_negative) + atf_tc_fail("%s:%d iteration %d signbitf is wrong" + " about the sign of %f", __func__, + __LINE__, i, iterator_f); + if (signbit(iterator_d) != values[i].is_negative) + atf_tc_fail("%s:%d iteration %d signbit is wrong" + "about the sign of %f", __func__, + __LINE__,i, iterator_d); + +#ifdef __HAVE_LONG_DOUBLE + long double iterator_l = values[i].input; + if (signbit(iterator_l) != values[i].is_negative) + atf_tc_fail("%s:%d iteration %d signbitl is wrong" + " about the sign of %Lf", __func__, + __LINE__, i, iterator_l); +#endif + } + +#ifdef __HAVE_LONG_DOUBLE + for (unsigned int i = 0; i < __arraycount(ldbl_values); i++) { + if (signbit(ldbl_values[i].input) != ldbl_values[i].is_negative) + atf_tc_fail("%s:%d iteration %d signbitl is" + "wrong about the sign of %Lf", + __func__, __LINE__, i, + ldbl_values[i].input); + } +#endif + +} + +ATF_TP_ADD_TCS(tp) +{ + + ATF_TP_ADD_TC(tp, signbit); + + return atf_no_error(); +} diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_cabsl.cxx similarity index 59% copy from contrib/netbsd-tests/lib/libm/t_fmod.c copy to contrib/netbsd-tests/lib/libm/t_cabsl.cxx index 2a221f5f62e1..7dd119b1da3b 100644 --- a/contrib/netbsd-tests/lib/libm/t_fmod.c +++ b/contrib/netbsd-tests/lib/libm/t_cabsl.cxx @@ -1,76 +1,66 @@ -/* $NetBSD: t_fmod.c,v 1.3 2015/01/03 14:23:53 gson Exp $ */ - /*- - * Copyright (c) 2013 The NetBSD Foundation, Inc. + * Copyright (c) 2018 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation - * by Joerg Sonnenberger. + * by Maya Rashish * * 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 -#include -#include +/* + * Test that C++ "cabsl" is usable. PR lib/50646 + */ -#include "isqemu.h" +#include +#include -ATF_TC(fmod); -ATF_TC_HEAD(fmod, tc) +ATF_TEST_CASE(cabsl); +ATF_TEST_CASE_HEAD(cabsl) { - atf_tc_set_md_var(tc, "descr","Check fmod family"); + set_md_var("descr", "Check that cabsl is usable from C++"); } - -ATF_TC_BODY(fmod, tc) +ATF_TEST_CASE_BODY(cabsl) { -#ifdef __NetBSD__ - if (isQEMU()) - atf_tc_expect_fail("PR misc/44767"); -#endif + int sum = 0; - ATF_CHECK(fmodf(2.0, 1.0) == 0); - ATF_CHECK(fmod(2.0, 1.0) == 0); -#if !defined(__FreeBSD__) || LDBL_PREC != 53 - ATF_CHECK(fmodl(2.0, 1.0) == 0); +#ifdef __HAVE_LONG_DOUBLE + std::complex cld(3.0,4.0); + sum += std::abs(cld); #endif + std::complex cd(3.0,4.0); + sum += std::abs(cd); - ATF_CHECK(fmodf(2.0, 0.5) == 0); - ATF_CHECK(fmod(2.0, 0.5) == 0); -#if !defined(__FreeBSD__) || LDBL_PREC != 53 - ATF_CHECK(fmodl(2.0, 0.5) == 0); -#endif + std::complex cf(3.0,4.0); + sum += std::abs(cf); - 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); -#if !defined(__FreeBSD__) || LDBL_PREC != 53 - ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON); +#ifdef __HAVE_LONG_DOUBLE + ATF_REQUIRE_EQ(sum, 3*5); +#else + ATF_REQUIRE_EQ(sum, 2*5); #endif } -ATF_TP_ADD_TCS(tp) +ATF_INIT_TEST_CASES(tcs) { - - ATF_TP_ADD_TC(tp, fmod); - - return atf_no_error(); + ATF_ADD_TEST_CASE(tcs, cabsl); } diff --git a/contrib/netbsd-tests/lib/libm/t_cbrt.c b/contrib/netbsd-tests/lib/libm/t_cbrt.c index 08e9faeb145c..639bc7e06517 100644 --- a/contrib/netbsd-tests/lib/libm/t_cbrt.c +++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c @@ -1,379 +1,412 @@ -/* $NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_cbrt.c,v 1.5 2018/11/15 05:14:20 riastradh 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 -__RCSID("$NetBSD: t_cbrt.c,v 1.3 2014/03/03 10:39:08 martin Exp $"); +__RCSID("$NetBSD: t_cbrt.c,v 1.5 2018/11/15 05:14:20 riastradh Exp $"); #include +#include #include #include /* * 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; + /* Neither cbrt nor pow is required to be correctly rounded. */ + const double eps = 2*DBL_EPSILON; 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]); + double x_cbrt = cbrt(x[i]); + double x_pow13 = pow(x[i], 1.0 / 3.0); + bool ok; + + if (x[i] == 0) { + ok = (x_cbrt == x_pow13); + } else { + ok = (fabs((x_cbrt - x_pow13)/x_cbrt) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("cbrt(%.17g) = %.17g != " + "pow(%.17g, 1/3) = %.17g\n", + x[i], x_cbrt, x[i], x_pow13); + } } } 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; + /* Neither cbrt nor pow is required to be correctly rounded. */ + const float eps = 2*FLT_EPSILON; 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]); + float x_cbrt = cbrtf(x[i]); + float x_pow13 = powf(x[i], 1.0 / 3.0); + bool ok; + + if (x[i] == 0) { + ok = (x_cbrt == x_pow13); + } else { + ok = (fabsf((x_cbrt - x_pow13)/x_cbrt) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("cbrtf(%.9g) = %.9g. != " + "powf(%.9g, 1/3) = %.9g\n", + (double)x[i], (double)x_cbrt, + (double)x[i], (double)x_pow13); + } } } 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"); } #if !defined(__FreeBSD__) || LDBL_PREC != 53 /* * 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; + /* Neither cbrt nor pow is required to be correctly rounded. */ + const long double eps = 2*LDBL_EPSILON; size_t i; #if defined(__amd64__) && defined(__clang__) && __clang_major__ >= 7 && \ __clang_major__ < 10 && __FreeBSD_cc_version < 1300002 atf_tc_expect_fail("test fails with clang 7-9 - bug 234040"); #endif - for (i = 0; i < __arraycount(x); i++) { - - y = cbrtl(x[i]); + long double x_cbrt = cbrtl(x[i]); #ifdef __FreeBSD__ - z = powl(x[i], (long double)1.0 / 3.0); + /* + * NetBSD doesn't have a real powl/cbrtl implementation, they + * just call the double version. On FreeBSD we have a real + * powl implementation so we have to cast the second argument + * to long double before dividing to get a more precise + * approximation of 1/3. + * TODO: upstream this diff. + */ + long double x_pow13 = powl(x[i], (long double)1.0 / 3.0); #else - z = powl(x[i], 1.0 / 3.0); + long double x_pow13 = powl(x[i], 1.0 / 3.0); #endif - - 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]); + bool ok; + + if (x[i] == 0) { + ok = (x_cbrt == x_pow13); + } else { + ok = (fabsl((x_cbrt - x_pow13)/x_cbrt) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("cbrtl(%.35Lg) = %.35Lg != " + "powl(%.35Lg, 1/3) = %.35Lg\n", + x[i], x_cbrt, x[i], x_pow13); + } } } 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"); } #endif 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); #if !defined(__FreeBSD__) || LDBL_PREC != 53 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); #endif return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libm/t_cos.c b/contrib/netbsd-tests/lib/libm/t_cos.c index d99d60810eeb..ca5f0aab7ffa 100644 --- a/contrib/netbsd-tests/lib/libm/t_cos.c +++ b/contrib/netbsd-tests/lib/libm/t_cos.c @@ -1,263 +1,399 @@ -/* $NetBSD: t_cos.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_cos.c,v 1.9 2019/05/27 00:10:36 maya 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 #include +#include #include static const struct { int angle; double x; double y; + float fy; } 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 } + { -180, -3.141592653589793, -1.0000000000000000, 999 }, + { -135, -2.356194490192345, -0.7071067811865476, 999 }, + { -90, -1.5707963267948966, 6.123233995736766e-17, -4.3711388e-08 }, + { -90, -1.5707963267948968, -1.6081226496766366e-16, -4.3711388e-08 }, + { -45, -0.785398163397448, 0.7071067811865478, 999 }, + { 0, 0.000000000000000, 1.0000000000000000, 999 }, + { 30, 0.523598775598299, 0.8660254037844386, 999 }, + { 45, 0.785398163397448, 0.7071067811865478, 999 }, + { 60, 1.0471975511965976, 0.5000000000000001, 999 }, + { 60, 1.0471975511965979, 0.4999999999999999, 999 }, + { 90, 1.570796326794897, -3.8285686989269494e-16, -4.3711388e-08 }, + { 120, 2.0943951023931953, -0.4999999999999998, 999 }, + { 120, 2.0943951023931957, -0.5000000000000002, 999 }, + { 135, 2.356194490192345, -0.7071067811865476, 999 }, + { 150, 2.617993877991494, -0.8660254037844386, 999 }, + { 180, 3.141592653589793, -1.0000000000000000, 999 }, + { 270, 4.712388980384690, -1.8369701987210297e-16, 1.1924881e-08 }, + { 360, 6.283185307179586, 1.0000000000000000, 999 }, }; +#ifdef __HAVE_LONG_DOUBLE +/* + * cosl(3) + */ +ATF_TC(cosl_angles); +ATF_TC_HEAD(cosl_angles, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test some selected angles"); +} + +ATF_TC_BODY(cosl_angles, tc) +{ + /* + * XXX The given data is for double, so take that + * into account and expect less precise results.. + */ + const long double eps = DBL_EPSILON; + size_t i; + + for (i = 0; i < __arraycount(angles); i++) { + int deg = angles[i].angle; + long double theta = angles[i].x; + long double cos_theta = angles[i].y; + + assert(cos_theta != 0); + if (!(fabsl((cosl(theta) - cos_theta)/cos_theta) <= eps)) { + atf_tc_fail_nonfatal("cos(%d deg = %.17Lg) = %.17Lg" + " != %.17Lg", + deg, theta, cosl(theta), cos_theta); + } + } +} + +ATF_TC(cosl_nan); +ATF_TC_HEAD(cosl_nan, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosl(NaN) == NaN"); +} + +ATF_TC_BODY(cosl_nan, tc) +{ + const long double x = 0.0L / 0.0L; + + ATF_CHECK(isnan(x) != 0); + ATF_CHECK(isnan(cosl(x)) != 0); +} + +ATF_TC(cosl_inf_neg); +ATF_TC_HEAD(cosl_inf_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosl(-Inf) == NaN"); +} + +ATF_TC_BODY(cosl_inf_neg, tc) +{ + const long double x = -1.0L / 0.0L; + + ATF_CHECK(isnan(cosl(x)) != 0); +} + +ATF_TC(cosl_inf_pos); +ATF_TC_HEAD(cosl_inf_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosl(+Inf) == NaN"); +} + +ATF_TC_BODY(cosl_inf_pos, tc) +{ + const long double x = 1.0L / 0.0L; + + ATF_CHECK(isnan(cosl(x)) != 0); +} + + +ATF_TC(cosl_zero_neg); +ATF_TC_HEAD(cosl_zero_neg, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosl(-0.0) == 1.0"); +} + +ATF_TC_BODY(cosl_zero_neg, tc) +{ + const long double x = -0.0L; + + ATF_CHECK(cosl(x) == 1.0); +} + +ATF_TC(cosl_zero_pos); +ATF_TC_HEAD(cosl_zero_pos, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test cosl(+0.0) == 1.0"); +} + +ATF_TC_BODY(cosl_zero_pos, tc) +{ + const long double x = 0.0L; + + ATF_CHECK(cosl(x) == 1.0); +} +#endif + /* * 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; + const double eps = DBL_EPSILON; 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); + int deg = angles[i].angle; + double theta = angles[i].x; + double cos_theta = angles[i].y; + + assert(cos_theta != 0); + if (!(fabs((cos(theta) - cos_theta)/cos_theta) <= eps)) { + atf_tc_fail_nonfatal("cos(%d deg = %.17g) = %.17g" + " != %.17g", + deg, theta, cos(theta), cos_theta); + } } } 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; + const float eps = FLT_EPSILON; 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); + int deg = angles[i].angle; + float theta = angles[i].x; + float cos_theta = angles[i].fy; + + /* + * Force rounding to float even if FLT_EVAL_METHOD=2, + * as is the case on i386. + * + * The volatile should not be necessary, by C99 Sec. + * 5.2.4.2.2. para. 8 on p. 24 which specifies that + * assignment and cast remove all extra range and precision, + * but seems to be needed to work around a compiler bug. + */ + volatile float result = cosf(theta); + + if (cos_theta == 999) + cos_theta = angles[i].y; + + assert(cos_theta != 0); + if (!(fabsf((result - cos_theta)/cos_theta) <= eps)) { + atf_tc_fail_nonfatal("cosf(%d deg = %.8g) = %.8g" + " != %.8g", deg, theta, result, cos_theta); + } } } 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) { +#ifdef __HAVE_LONG_DOUBLE + ATF_TP_ADD_TC(tp, cosl_angles); + ATF_TP_ADD_TC(tp, cosl_nan); + ATF_TP_ADD_TC(tp, cosl_inf_neg); + ATF_TP_ADD_TC(tp, cosl_inf_pos); + ATF_TP_ADD_TC(tp, cosl_zero_neg); + ATF_TP_ADD_TC(tp, cosl_zero_pos); +#endif 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/contrib/netbsd-tests/lib/libm/t_cosh.c b/contrib/netbsd-tests/lib/libm/t_cosh.c index 3f998de761bb..aac3a39b0236 100644 --- a/contrib/netbsd-tests/lib/libm/t_cosh.c +++ b/contrib/netbsd-tests/lib/libm/t_cosh.c @@ -1,270 +1,268 @@ -/* $NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_cosh.c,v 1.7 2018/11/07 03:59:36 riastradh 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 -__RCSID("$NetBSD: t_cosh.c,v 1.6 2014/03/03 10:39:08 martin Exp $"); +__RCSID("$NetBSD: t_cosh.c,v 1.7 2018/11/07 03:59:36 riastradh Exp $"); #include +#include #include #include 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, }, + { -10, 11013.232920103323, }, + { -2, 3.762195691083631, }, + { -1, 1.543080634815244, }, + { -0.05, 1.001250260438369, }, + { -0.001, 1.0000005000000418, }, + { 0, 1, }, + { 0.001, 1.0000005000000418, }, + { 0.05, 1.001250260438369, }, + { 1, 1.543080634815244, }, + { 2, 3.762195691083631, }, + { 10, 11013.232920103323, }, }; /* * 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; + const double eps = DBL_EPSILON; size_t i; for (i = 0; i < __arraycount(values); i++) { - x = values[i].x; - y = values[i].y; - eps = 1e-15 * values[i].e; + double x = values[i].x; + double cosh_x = values[i].y; - if (fabs(cosh(x) - y) > eps) - atf_tc_fail_nonfatal("cosh(%g) != %g\n", x, y); + if (!(fabs((cosh(x) - cosh_x)/cosh_x) <= eps)) { + atf_tc_fail_nonfatal("cosh(%.17g) = %.17g != %.17g\n", + x, cosh(x), cosh_x); + } } } 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; + const float eps = FLT_EPSILON; size_t i; for (i = 0; i < __arraycount(values); i++) { - x = values[i].x; - y = values[i].y; - eps = 1e-6 * values[i].e; + float x = values[i].x; + float cosh_x = values[i].y; - if (fabsf(coshf(x) - y) > eps) - atf_tc_fail_nonfatal("coshf(%g) != %g\n", x, y); + if (!(fabsf((coshf(x) - cosh_x)/cosh_x) <= eps)) { + atf_tc_fail_nonfatal("coshf(%.17g) = %.17g != %.17g\n", + x, coshf(x), cosh_x); + } } } 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/contrib/netbsd-tests/lib/libm/t_exp.c b/contrib/netbsd-tests/lib/libm/t_exp.c index 0eb6412b566e..acef4c0e91de 100644 --- a/contrib/netbsd-tests/lib/libm/t_exp.c +++ b/contrib/netbsd-tests/lib/libm/t_exp.c @@ -1,569 +1,567 @@ -/* $NetBSD: t_exp.c,v 1.8 2014/10/07 16:53:44 gson Exp $ */ +/* $NetBSD: t_exp.c,v 1.9 2018/11/07 03:59:36 riastradh 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 +#include #include #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, }, + { -10, 0.4539992976248485e-4, }, + { -5, 0.6737946999085467e-2, }, + { -1, 0.3678794411714423, }, + { -0.1, 0.9048374180359595, }, + { 0, 1.0000000000000000, }, + { 0.1, 1.1051709180756477, }, + { 1, 2.7182818284590452, }, + { 5, 148.41315910257660, }, + { 10, 22026.465794806718, }, }; /* * 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; #if defined(__FreeBSD__) && defined(__i386__) atf_tc_expect_fail("a number of the assertions fail on i386"); #endif 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 d_y; float f_y; double d_eps; double f_eps; } v[] = { #if __DBL_MAX_EXP__ > 128 /* The largest double constant */ { 0x1.fffffffffffffp9, 0x1.ffffffffffd3ap1023, 0.00, 0x1p969, 0.0 }, /* The largest float constant */ { 0x1.fffffep6, 0x1.ffff4ep+127, 0x1.ffff4ep+127, 6e30, 0.0 }, #endif #ifdef T_LIBM_PLUS_INF { 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 */ /* f_y values calculated using py-mpmath */ { 1.1, 0x1.125fbee250664p+1, 0x1.125fc0p+1, 0x1p-52, 0x1.8p-22 }, { 2.2, 0x1.2611186bae675p+2, 0x1.26111ap+2, 0x1p-51, 0x1.8p-21 }, { 3.3, 0x1.3b2c47bff8328p+3, 0x1.3b2c48p+3, 0x1p-50, 0x1.8p-20 }, { 4.4, 0x1.51cb453b9536ep+4, 0x1.51cb46p+4, 0x1p-49, 0x1.8p-19 }, { 5.5, 0x1.6a09e667f3bcdp+5, 0x1.6a09e6p+5, 0x1p-48, 0x1.8p-18 }, { 6.6, 0x1.8406003b2ae5bp+6, 0x1.8405fep+6, 0x1p-47, 0x1.8p-17 }, { 7.7, 0x1.9fdf8bcce533ep+7, 0x1.9fdf88p+7, 0x1p-46, 0x1.8p-16 }, { 8.8, 0x1.bdb8cdadbe124p+8, 0x1.bdb8d2p+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].d_y, v[i].d_eps); if (i > 1) T_LIBM_CHECK(i, exp2f, v[i].x, v[i].f_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; + const double eps = DBL_EPSILON; 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; + double x = exp_values[i].x; + double e_x = exp_values[i].y; - if (fabs(exp(x) - y) > eps) - atf_tc_fail_nonfatal("exp(%0.01f) != %18.18e", x, y); + if (!(fabs((exp(x) - e_x)/e_x) <= eps)) { + atf_tc_fail_nonfatal("exp(%.17g) = %.17g != %.17g", + x, exp(x), e_x); + } } } 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; + const float eps = FLT_EPSILON; 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; + float x = exp_values[i].x; + float e_x = exp_values[i].y; - if (fabsf(expf(x) - y) > eps) - atf_tc_fail_nonfatal("expf(%0.01f) != %18.18e", x, y); + if (!(fabsf((expf(x) - e_x)/e_x) <= eps)) { + atf_tc_fail_nonfatal("expf(%.8g) = %.8g != %.8g", + x, exp(x), e_x); + } } } 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/contrib/netbsd-tests/lib/libm/t_fe_round.c b/contrib/netbsd-tests/lib/libm/t_fe_round.c index fe805b4f86b8..33da289eb156 100644 --- a/contrib/netbsd-tests/lib/libm/t_fe_round.c +++ b/contrib/netbsd-tests/lib/libm/t_fe_round.c @@ -1,124 +1,258 @@ /* * Written by Maya Rashish * Public domain. * * Testing IEEE-754 rounding modes (and lrint) */ #include #include #ifdef __HAVE_FENV #include #include #include /*#pragma STDC FENV_ACCESS ON gcc?? */ #define INT 9223L #define EPSILON 0.001 static const struct { int round_mode; double input; long int expected; } values[] = { { FE_DOWNWARD, 3.7, 3}, { FE_DOWNWARD, -3.7, -4}, { FE_DOWNWARD, +0, 0}, { FE_DOWNWARD, -INT-0.01, -INT-1}, { FE_DOWNWARD, +INT-0.01, INT-1}, { FE_DOWNWARD, -INT+0.01, -INT}, { FE_DOWNWARD, +INT+0.01, INT}, #if 0 /* cpu bugs? */ { FE_DOWNWARD, -0, -1}, { FE_UPWARD, +0, 1}, #endif { FE_UPWARD, -0, 0}, { FE_UPWARD, -123.7, -123}, { FE_UPWARD, 123.999, 124}, { FE_UPWARD, -INT-0.01, -INT}, { FE_UPWARD, +INT-0.01, INT}, { FE_UPWARD, -INT+0.01, -INT+1}, { FE_UPWARD, +INT+0.01, INT+1}, { FE_TOWARDZERO, 1.99, 1}, { FE_TOWARDZERO, -1.99, -1}, { FE_TOWARDZERO, 0.2, 0}, { FE_TOWARDZERO, INT+0.01, INT}, { FE_TOWARDZERO, INT-0.01, INT - 1}, { FE_TOWARDZERO, -INT+0.01, -INT + 1}, { FE_TOWARDZERO, +0, 0}, { FE_TOWARDZERO, -0, 0}, { FE_TONEAREST, -INT-0.01, -INT}, { FE_TONEAREST, +INT-0.01, INT}, { FE_TONEAREST, -INT+0.01, -INT}, { FE_TONEAREST, +INT+0.01, INT}, { FE_TONEAREST, -INT-0.501, -INT-1}, { FE_TONEAREST, +INT-0.501, INT-1}, { FE_TONEAREST, -INT+0.501, -INT+1}, { FE_TONEAREST, +INT+0.501, INT+1}, { FE_TONEAREST, +0, 0}, { FE_TONEAREST, -0, 0}, }; ATF_TC(fe_round); ATF_TC_HEAD(fe_round, tc) { atf_tc_set_md_var(tc, "descr","Checking IEEE 754 rounding modes using lrint"); } ATF_TC_BODY(fe_round, tc) { long int received; for (unsigned int i = 0; i < __arraycount(values); i++) { fesetround(values[i].round_mode); received = lrint(values[i].input); ATF_CHECK_MSG( (labs(received - values[i].expected) < EPSILON), "lrint rounding wrong, difference too large\n" "input: %f (index %d): got %ld, expected %ld\n", values[i].input, i, received, values[i].expected); /* Do we get the same rounding mode out? */ ATF_CHECK_MSG( (fegetround() == values[i].round_mode), "Didn't get the same rounding mode out!\n" "(index %d) fed in %d rounding mode, got %d out\n", - i, fegetround(), values[i].round_mode); + i, values[i].round_mode, fegetround()); + } +} + +ATF_TC(fe_nearbyint); +ATF_TC_HEAD(fe_nearbyint, tc) +{ + atf_tc_set_md_var(tc, "descr","Checking IEEE 754 rounding modes using nearbyint"); +} + +ATF_TC_BODY(fe_nearbyint, tc) +{ + double received; + + for (unsigned int i = 0; i < __arraycount(values); i++) { + fesetround(values[i].round_mode); + + received = nearbyint(values[i].input); + ATF_CHECK_MSG( + (fabs(received - values[i].expected) < EPSILON), + "nearbyint rounding wrong, difference too large\n" + "input: %f (index %d): got %f, expected %ld\n", + values[i].input, i, received, values[i].expected); + + /* Do we get the same rounding mode out? */ + ATF_CHECK_MSG( + (fegetround() == values[i].round_mode), + "Didn't get the same rounding mode out!\n" + "(index %d) fed in %d rounding mode, got %d out\n", + i, values[i].round_mode, fegetround()); + } +} + +static const struct { + double input; + double toward; + double expected; +} values2[] = { + { 10.0, 11.0, 10.0 }, + { -5.0, -6.0, -5.0 }, +}; + +ATF_TC(fe_nextafter); +ATF_TC_HEAD(fe_nextafter, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checking IEEE 754 rounding using nextafter()"); +} + +ATF_TC_BODY(fe_nextafter, tc) +{ + double received; + int res; + + for (unsigned int i = 0; i < __arraycount(values2); i++) { + received = nextafter(values2[i].input, values2[i].toward); + if (values2[i].input < values2[i].toward) { + res = (received > values2[i].input); + } else { + res = (received < values2[i].input); + } + ATF_CHECK_MSG( + res && (fabs(received - values2[i].expected) < EPSILON), + "nextafter() rounding wrong, difference too large\n" + "input: %f (index %d): got %f, expected %f, res %d\n", + values2[i].input, i, received, values2[i].expected, res); + } +} + +ATF_TC(fe_nexttoward); +ATF_TC_HEAD(fe_nexttoward, tc) +{ + atf_tc_set_md_var(tc, "descr", "Checking IEEE 754 rounding using nexttoward()"); +} + +ATF_TC_BODY(fe_nexttoward, tc) +{ + double received; + int res; + + for (unsigned int i = 0; i < __arraycount(values2); i++) { + received = nexttoward(values2[i].input, values2[i].toward); + if (values2[i].input < values2[i].toward) { + res = (received > values2[i].input); + } else { + res = (received < values2[i].input); + } + ATF_CHECK_MSG( + res && (fabs(received - values2[i].expected) < EPSILON), + "nexttoward() rounding wrong, difference too large\n" + "input: %f (index %d): got %f, expected %f, res %d\n", + values2[i].input, i, received, values2[i].expected, res); } } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fe_round); + ATF_TP_ADD_TC(tp, fe_nearbyint); + ATF_TP_ADD_TC(tp, fe_nextafter); + ATF_TP_ADD_TC(tp, fe_nexttoward); return atf_no_error(); } #else ATF_TC(t_nofe_round); ATF_TC_HEAD(t_nofe_round, tc) { atf_tc_set_md_var(tc, "descr", "dummy test case - no fenv.h support"); } - ATF_TC_BODY(t_nofe_round, tc) { atf_tc_skip("no fenv.h support on this architecture"); } +ATF_TC(t_nofe_nearbyint); + +ATF_TC_HEAD(t_nofe_nearbyint, tc) +{ + atf_tc_set_md_var(tc, "descr", + "dummy test case - no fenv.h support"); +} + +ATF_TC_BODY(t_nofe_nearbyint, tc) +{ + atf_tc_skip("no fenv.h support on this architecture"); +} + +ATF_TC(t_nofe_nextafter); + +ATF_TC_HEAD(t_nofe_nextafter, tc) +{ + atf_tc_set_md_var(tc, "descr", + "dummy test case - no fenv.h support"); +} + +ATF_TC_BODY(t_nofe_nextafter, tc) +{ + atf_tc_skip("no fenv.h support on this architecture"); +} + +ATF_TC(t_nofe_nexttoward); + +ATF_TC_HEAD(t_nofe_nexttoward, tc) +{ + atf_tc_set_md_var(tc, "descr", + "dummy test case - no fenv.h support"); +} + +ATF_TC_BODY(t_nofe_nexttoward, tc) +{ + atf_tc_skip("no fenv.h support on this architecture"); +} + ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, t_nofe_round); + ATF_TP_ADD_TC(tp, t_nofe_nearbyint); + ATF_TP_ADD_TC(tp, t_nofe_nextafter); + ATF_TP_ADD_TC(tp, t_nofe_nexttoward); return atf_no_error(); } #endif diff --git a/contrib/netbsd-tests/lib/libm/t_fenv.c b/contrib/netbsd-tests/lib/libm/t_fenv.c index 544503673a98..613bf3027950 100644 --- a/contrib/netbsd-tests/lib/libm/t_fenv.c +++ b/contrib/netbsd-tests/lib/libm/t_fenv.c @@ -1,220 +1,220 @@ -/* $NetBSD: t_fenv.c,v 1.3 2015/12/22 14:20:59 christos Exp $ */ +/* $NetBSD: t_fenv.c,v 1.6 2019/04/25 20:48:54 kamil Exp $ */ /*- * Copyright (c) 2014 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Martin Husemann. * * 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 -__RCSID("$NetBSD: t_fenv.c,v 1.3 2015/12/22 14:20:59 christos Exp $"); +__RCSID("$NetBSD: t_fenv.c,v 1.6 2019/04/25 20:48:54 kamil Exp $"); #include #include #ifdef __HAVE_FENV #include #include -#if __arm__ && !__SOFTFP__ +#if (__arm__ && !__SOFTFP__) || __aarch64__ /* - * Some NEON fpus do not implement IEEE exception handling, - * skip these tests if running on them and compiled for + * Some NEON fpus do not trap on IEEE 754 FP exceptions. + * Skip these tests if running on them and compiled for * hard float. */ #define FPU_EXC_PREREQ() \ if (0 == fpsetmask(fpsetmask(FP_X_INV))) \ - atf_tc_skip("FPU does not implement exception handling"); + atf_tc_skip("FPU does not implement traps on FP exceptions"); /* * Same as above: some don't allow configuring the rounding mode. */ #define FPU_RND_PREREQ() \ if (0 == fpsetround(fpsetround(FP_RZ))) \ atf_tc_skip("FPU does not implement configurable " \ "rounding modes"); #endif #ifndef FPU_EXC_PREREQ #define FPU_EXC_PREREQ() /* nothing */ #endif #ifndef FPU_RND_PREREQ #define FPU_RND_PREREQ() /* nothing */ #endif ATF_TC(fegetround); ATF_TC_HEAD(fegetround, tc) { atf_tc_set_md_var(tc, "descr", "verify the fegetround() function agrees with the legacy " "fpsetround"); } ATF_TC_BODY(fegetround, tc) { FPU_RND_PREREQ(); fpsetround(FP_RZ); ATF_CHECK(fegetround() == FE_TOWARDZERO); fpsetround(FP_RM); ATF_CHECK(fegetround() == FE_DOWNWARD); fpsetround(FP_RN); ATF_CHECK(fegetround() == FE_TONEAREST); fpsetround(FP_RP); ATF_CHECK(fegetround() == FE_UPWARD); } ATF_TC(fesetround); ATF_TC_HEAD(fesetround, tc) { atf_tc_set_md_var(tc, "descr", "verify the fesetround() function agrees with the legacy " "fpgetround"); } ATF_TC_BODY(fesetround, tc) { FPU_RND_PREREQ(); fesetround(FE_TOWARDZERO); ATF_CHECK(fpgetround() == FP_RZ); fesetround(FE_DOWNWARD); ATF_CHECK(fpgetround() == FP_RM); fesetround(FE_TONEAREST); ATF_CHECK(fpgetround() == FP_RN); fesetround(FE_UPWARD); ATF_CHECK(fpgetround() == FP_RP); } ATF_TC(fegetexcept); ATF_TC_HEAD(fegetexcept, tc) { atf_tc_set_md_var(tc, "descr", "verify the fegetexcept() function agrees with the legacy " "fpsetmask()"); } ATF_TC_BODY(fegetexcept, tc) { FPU_EXC_PREREQ(); fpsetmask(0); ATF_CHECK(fegetexcept() == 0); fpsetmask(FP_X_INV|FP_X_DZ|FP_X_OFL|FP_X_UFL|FP_X_IMP); ATF_CHECK(fegetexcept() == (FE_INVALID|FE_DIVBYZERO|FE_OVERFLOW |FE_UNDERFLOW|FE_INEXACT)); fpsetmask(FP_X_INV); ATF_CHECK(fegetexcept() == FE_INVALID); fpsetmask(FP_X_DZ); ATF_CHECK(fegetexcept() == FE_DIVBYZERO); fpsetmask(FP_X_OFL); ATF_CHECK(fegetexcept() == FE_OVERFLOW); fpsetmask(FP_X_UFL); ATF_CHECK(fegetexcept() == FE_UNDERFLOW); fpsetmask(FP_X_IMP); ATF_CHECK(fegetexcept() == FE_INEXACT); } ATF_TC(feenableexcept); ATF_TC_HEAD(feenableexcept, tc) { atf_tc_set_md_var(tc, "descr", "verify the feenableexcept() function agrees with the legacy " "fpgetmask()"); } ATF_TC_BODY(feenableexcept, tc) { FPU_EXC_PREREQ(); fedisableexcept(FE_ALL_EXCEPT); ATF_CHECK(fpgetmask() == 0); feenableexcept(FE_UNDERFLOW); ATF_CHECK(fpgetmask() == FP_X_UFL); fedisableexcept(FE_ALL_EXCEPT); feenableexcept(FE_OVERFLOW); ATF_CHECK(fpgetmask() == FP_X_OFL); fedisableexcept(FE_ALL_EXCEPT); feenableexcept(FE_DIVBYZERO); ATF_CHECK(fpgetmask() == FP_X_DZ); fedisableexcept(FE_ALL_EXCEPT); feenableexcept(FE_INEXACT); ATF_CHECK(fpgetmask() == FP_X_IMP); fedisableexcept(FE_ALL_EXCEPT); feenableexcept(FE_INVALID); ATF_CHECK(fpgetmask() == FP_X_INV); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fegetround); ATF_TP_ADD_TC(tp, fesetround); ATF_TP_ADD_TC(tp, fegetexcept); ATF_TP_ADD_TC(tp, feenableexcept); return atf_no_error(); } #else /* no fenv.h support */ ATF_TC(t_nofenv); ATF_TC_HEAD(t_nofenv, tc) { atf_tc_set_md_var(tc, "descr", "dummy test case - no fenv.h support"); } ATF_TC_BODY(t_nofenv, tc) { atf_tc_skip("no fenv.h support on this architecture"); } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, t_nofenv); return atf_no_error(); } #endif diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_fmod.c index 2a221f5f62e1..1866c3d23d21 100644 --- a/contrib/netbsd-tests/lib/libm/t_fmod.c +++ b/contrib/netbsd-tests/lib/libm/t_fmod.c @@ -1,76 +1,70 @@ -/* $NetBSD: t_fmod.c,v 1.3 2015/01/03 14:23:53 gson Exp $ */ +/* $NetBSD: t_fmod.c,v 1.4 2020/08/25 13:39:16 gson 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 #include #include #include "isqemu.h" ATF_TC(fmod); ATF_TC_HEAD(fmod, tc) { atf_tc_set_md_var(tc, "descr","Check fmod family"); } ATF_TC_BODY(fmod, tc) { #ifdef __NetBSD__ if (isQEMU()) atf_tc_expect_fail("PR misc/44767"); #endif ATF_CHECK(fmodf(2.0, 1.0) == 0); ATF_CHECK(fmod(2.0, 1.0) == 0); -#if !defined(__FreeBSD__) || LDBL_PREC != 53 ATF_CHECK(fmodl(2.0, 1.0) == 0); -#endif ATF_CHECK(fmodf(2.0, 0.5) == 0); ATF_CHECK(fmod(2.0, 0.5) == 0); -#if !defined(__FreeBSD__) || LDBL_PREC != 53 ATF_CHECK(fmodl(2.0, 0.5) == 0); -#endif 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); -#if !defined(__FreeBSD__) || LDBL_PREC != 53 ATF_CHECK(fabsl(fmodl(1.0, 0.1L) - 0.1L) <= 55 * LDBL_EPSILON); -#endif } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, fmod); return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libm/t_ilogb.c b/contrib/netbsd-tests/lib/libm/t_ilogb.c index 1d35cb64127b..bbccaca39bc1 100644 --- a/contrib/netbsd-tests/lib/libm/t_ilogb.c +++ b/contrib/netbsd-tests/lib/libm/t_ilogb.c @@ -1,130 +1,132 @@ -/* $NetBSD: t_ilogb.c,v 1.7 2017/01/13 19:23:40 christos Exp $ */ +/* $NetBSD: t_ilogb.c,v 1.9 2018/06/14 21:57:25 maya Exp $ */ /*- * Copyright (c) 2016 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation * by Maya Rashish. * * 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 -__RCSID("$NetBSD: t_ilogb.c,v 1.7 2017/01/13 19:23:40 christos Exp $"); +__RCSID("$NetBSD: t_ilogb.c,v 1.9 2018/06/14 21:57:25 maya Exp $"); #include #include #include #include #ifndef __HAVE_FENV # define ATF_CHECK_RAISED_INVALID # define ATF_CHECK_RAISED_NOTHING #else # define ATF_CHECK_RAISED_INVALID do { \ int r = fetestexcept(FE_ALL_EXCEPT); \ - ATF_CHECK_MSG(r == FE_INVALID, "r=%#x != %#x\n", r, FE_INVALID); \ + ATF_CHECK_MSG((r & FE_INVALID) != 0, \ + "r & FE_INVALID == 0 (r=%#x, FE_INVALID=%#x)\n", \ + r, FE_INVALID); \ (void)feclearexcept(FE_ALL_EXCEPT); \ } while (/*CONSTCOND*/0) # define ATF_CHECK_RAISED_NOTHING do { \ int r = fetestexcept(FE_ALL_EXCEPT); \ ATF_CHECK_MSG(r == 0, "r=%#x != 0\n", r); \ (void)feclearexcept(FE_ALL_EXCEPT); \ } while (/*CONSTCOND*/0) #endif ATF_TC(ilogb); ATF_TC_HEAD(ilogb, tc) { atf_tc_set_md_var(tc, "descr","Check ilogb family"); } ATF_TC_BODY(ilogb, tc) { ATF_CHECK(ilogbf(0) == FP_ILOGB0); ATF_CHECK_RAISED_INVALID; ATF_CHECK(ilogb(0) == FP_ILOGB0); ATF_CHECK_RAISED_INVALID; #ifdef __HAVE_LONG_DOUBLE ATF_CHECK(ilogbl(0) == FP_ILOGB0); ATF_CHECK_RAISED_INVALID; #endif ATF_CHECK(ilogbf(-0) == FP_ILOGB0); ATF_CHECK_RAISED_INVALID; ATF_CHECK(ilogb(-0) == FP_ILOGB0); ATF_CHECK_RAISED_INVALID; #ifdef __HAVE_LONG_DOUBLE ATF_CHECK(ilogbl(-0) == FP_ILOGB0); ATF_CHECK_RAISED_INVALID; #endif ATF_CHECK(ilogbf(INFINITY) == INT_MAX); ATF_CHECK_RAISED_INVALID; ATF_CHECK(ilogb(INFINITY) == INT_MAX); ATF_CHECK_RAISED_INVALID; #ifdef __HAVE_LONG_DOUBLE ATF_CHECK(ilogbl(INFINITY) == INT_MAX); ATF_CHECK_RAISED_INVALID; #endif ATF_CHECK(ilogbf(-INFINITY) == INT_MAX); ATF_CHECK_RAISED_INVALID; ATF_CHECK(ilogb(-INFINITY) == INT_MAX); ATF_CHECK_RAISED_INVALID; #ifdef __HAVE_LONG_DOUBLE ATF_CHECK(ilogbl(-INFINITY) == INT_MAX); ATF_CHECK_RAISED_INVALID; #endif ATF_CHECK(ilogbf(1024) == 10); ATF_CHECK_RAISED_NOTHING; ATF_CHECK(ilogb(1024) == 10); ATF_CHECK_RAISED_NOTHING; #ifdef __HAVE_LONG_DOUBLE ATF_CHECK(ilogbl(1024) == 10); ATF_CHECK_RAISED_NOTHING; #endif #ifndef __vax__ ATF_CHECK(ilogbf(NAN) == FP_ILOGBNAN); ATF_CHECK_RAISED_INVALID; ATF_CHECK(ilogb(NAN) == FP_ILOGBNAN); ATF_CHECK_RAISED_INVALID; #ifdef __HAVE_LONG_DOUBLE ATF_CHECK(ilogbl(NAN) == FP_ILOGBNAN); ATF_CHECK_RAISED_INVALID; #endif #endif } ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, ilogb); return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libm/t_ldexp.c b/contrib/netbsd-tests/lib/libm/t_ldexp.c index 251f2aeba5fb..977b2219873b 100644 --- a/contrib/netbsd-tests/lib/libm/t_ldexp.c +++ b/contrib/netbsd-tests/lib/libm/t_ldexp.c @@ -1,480 +1,475 @@ -/* $NetBSD: t_ldexp.c,v 1.16 2016/08/25 00:32:31 maya Exp $ */ +/* $NetBSD: t_ldexp.c,v 1.17 2018/11/07 03:59:36 riastradh 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 -__RCSID("$NetBSD: t_ldexp.c,v 1.16 2016/08/25 00:32:31 maya Exp $"); +__RCSID("$NetBSD: t_ldexp.c,v 1.17 2018/11/07 03:59:36 riastradh Exp $"); #include #include -#include +#include #include +#include #include #include #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" }, { 2.0, INT_MAX,SKIP, " inf" }, { -1.0, 1024, SKIP, " -inf" }, { -1.0, 1023, 1, " -inf" }, { -1.0, -1022, 2046, " -inf" }, { -1.0, 1025, SKIP, " -inf" }, { -2.0, INT_MAX,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) 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 eps = DBL_EPSILON; const double x = 12.0; - double y; size_t i; for (i = 0; i < __arraycount(n); i++) { + double y = ldexp(x, 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]); + if (!(fabs((y - (x * exp2(n[i])))/y) <= eps)) { + atf_tc_fail_nonfatal("ldexp(%.17g, %.17g) = %.17g " + "!= %.17g * exp2(%.17g) = %.17g", + x, n[i], y, x, n[i], (x * exp2(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 eps = FLT_EPSILON; const float x = 12.0; - float y; size_t i; for (i = 0; i < __arraycount(n); i++) { + float y = ldexpf(x, 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]); + if (!(fabsf((y - (x * exp2f(n[i])))/y) <= eps)) { + atf_tc_fail_nonfatal("ldexpf(%.17g, %.17g) = %.17g " + "!= %.17g * exp2f(%.17g) = %.17g", + x, n[i], y, x, n[i], (x * exp2f(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/contrib/netbsd-tests/lib/libm/t_libm.h b/contrib/netbsd-tests/lib/libm/t_libm.h index 34e3cb28abf5..0831f22d468d 100644 --- a/contrib/netbsd-tests/lib/libm/t_libm.h +++ b/contrib/netbsd-tests/lib/libm/t_libm.h @@ -1,62 +1,62 @@ -/* $NetBSD: t_libm.h,v 1.6 2014/03/25 17:30:14 joerg Exp $ */ +/* $NetBSD: t_libm.h,v 1.7 2018/11/07 03:59:36 riastradh 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) \ + long double e = fabsl((r - expect)/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/contrib/netbsd-tests/lib/libm/t_log.c b/contrib/netbsd-tests/lib/libm/t_log.c index 756efcf39769..41aae4c7c967 100644 --- a/contrib/netbsd-tests/lib/libm/t_log.c +++ b/contrib/netbsd-tests/lib/libm/t_log.c @@ -1,872 +1,874 @@ -/* $NetBSD: t_log.c,v 1.13 2015/02/09 19:39:48 martin Exp $ */ +/* $NetBSD: t_log.c,v 1.14 2018/11/07 03:59:36 riastradh 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 -__RCSID("$NetBSD: t_log.c,v 1.13 2015/02/09 19:39:48 martin Exp $"); +__RCSID("$NetBSD: t_log.c,v 1.14 2018/11/07 03:59:36 riastradh Exp $"); #include +#include #include #include #include /* * 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; 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; 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; + const double eps = DBL_EPSILON; - if (fabs(log(M_E) - 1.0) > eps) - atf_tc_fail_nonfatal("log(e) != 1"); + if (!(fabs(log(M_E) - 1.0) <= eps)) + atf_tc_fail_nonfatal("log(e) = %.17g != 1", log(M_E)); } 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; + const float eps = FLT_EPSILON; - if (fabsf(logf(M_E) - 1.0f) > eps) - atf_tc_fail_nonfatal("logf(e) != 1"); + if (!(fabsf(logf(M_E) - 1.0f) <= eps)) + atf_tc_fail_nonfatal("logf(e) = %.17g != 1", + (double)logf(M_E)); } 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; 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/contrib/netbsd-tests/lib/libm/t_round.c b/contrib/netbsd-tests/lib/libm/t_round.c index f47e1a0f8a13..7d32586f1aa5 100644 --- a/contrib/netbsd-tests/lib/libm/t_round.c +++ b/contrib/netbsd-tests/lib/libm/t_round.c @@ -1,85 +1,138 @@ -/* $NetBSD: t_round.c,v 1.4 2013/11/11 23:57:34 joerg Exp $ */ +/* $NetBSD: t_round.c,v 1.9 2017/09/03 13:41:19 wiz 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 + #include #include #include +#include +#include +#include /* * 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_TC(rounding_alpha); +ATF_TC_HEAD(rounding_alpha, tc) +{ + atf_tc_set_md_var(tc, "descr","Checking MPFR's config failure with -mieee on Alpha"); +} + +typedef uint64_t gimpy_limb_t; +#define GIMPY_NUMB_BITS 64 + +ATF_TC_BODY(rounding_alpha, tc) +{ + double d; + gimpy_limb_t u; + int i; + + d = 1.0; + for (i = 0; i < GIMPY_NUMB_BITS - 1; i++) + d = d + d; + + printf("d = %g\n", d); + u = (gimpy_limb_t) d; + + for (; i > 0; i--) { + ATF_CHECK_MSG((u % 2 == 0), + "%"PRIu64" is not an even number! (iteration %d)", u , i); + u = u >> 1; + } +} + +ATF_TC(rounding_alpha_simple); +ATF_TC_HEAD(rounding_alpha_simple, tc) +{ + atf_tc_set_md_var(tc, "descr","Checking double to uint64_t edge case"); +} + + +double rounding_alpha_simple_even = 9223372036854775808.000000; /* 2^63 */ + +ATF_TC_BODY(rounding_alpha_simple, tc) +{ + uint64_t unsigned_even = rounding_alpha_simple_even; + + ATF_CHECK_MSG(unsigned_even % 2 == 0, + "2^63 cast to uint64_t is odd (got %"PRIu64")", unsigned_even); + +} ATF_TP_ADD_TCS(tp) { ATF_TP_ADD_TC(tp, round_dir); + ATF_TP_ADD_TC(tp, rounding_alpha); + ATF_TP_ADD_TC(tp, rounding_alpha_simple); return atf_no_error(); } diff --git a/contrib/netbsd-tests/lib/libm/t_scalbn.c b/contrib/netbsd-tests/lib/libm/t_scalbn.c index 4bf00c3415d1..f6adaaa993ec 100644 --- a/contrib/netbsd-tests/lib/libm/t_scalbn.c +++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c @@ -1,526 +1,546 @@ -/* $NetBSD: t_scalbn.c,v 1.14 2017/01/13 21:09:12 agc Exp $ */ +/* $NetBSD: t_scalbn.c,v 1.16 2018/11/07 03:59:36 riastradh 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 -__RCSID("$NetBSD: t_scalbn.c,v 1.14 2017/01/13 21:09:12 agc Exp $"); +__RCSID("$NetBSD: t_scalbn.c,v 1.16 2018/11/07 03:59:36 riastradh Exp $"); #include #include #include #include +#include #include 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; + int except; }; 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 }, + { 0, 1.00085, 1.00085, 0, 0 }, + { 0, 0.99755, 0.99755, 0, 0 }, + { 0, -1.00085, -1.00085, 0, 0 }, + { 0, -0.99755, -0.99755, 0, 0 }, + { 1, 1.00085, 2.0* 1.00085, 0, 0 }, + { 1, 0.99755, 2.0* 0.99755, 0, 0 }, + { 1, -1.00085, 2.0* -1.00085, 0, 0 }, + { 1, -0.99755, 2.0* -0.99755, 0, 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++) { errno = 0; +#ifndef __vax__ + feclearexcept(FE_ALL_EXCEPT); +#endif 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); +#ifndef __vax__ + ATF_CHECK_EQ_MSG(errno, tests[i].error, + "test %zu: fetestexcept %d instead of %d", i, + fetestexcept(FE_INVALID | FE_DIVBYZERO | FE_OVERFLOW | FE_UNDERFLOW), + tests[i].except); +#endif + /* scalbn is always exact except for underflow or overflow. */ + ATF_CHECK_MSG(rv == tests[i].result, + "test %zu: return value %.17g instead of %.17g" + " (error %.17g)", + i, rv, tests[i].result, + fabs((tests[i].result - rv)/tests[i].result)); } } 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++) { errno = 0; 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); + /* scalbn is always exact except for underflow or overflow. */ + ATF_CHECK_MSG(rv == (float)tests[i].result, + "test %zu: return value %.8g instead of %.8g" + " (error %.8g)", + i, rv, tests[i].result, + fabs((tests[i].result - rv)/tests[i].result)); } } 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++) { errno = 0; 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); + /* scalbn is always exact except for underflow or overflow. */ + ATF_CHECK_MSG(rv == (long double)tests[i].result, + "test %zu: return value %.35Lg instead of %.35Lg" + " (error %.35Lg)", + i, rv, (long double)tests[i].result, + fabsl(((long double)tests[i].result - rv)/tests[i].result)); } #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/contrib/netbsd-tests/lib/libm/t_sin.c b/contrib/netbsd-tests/lib/libm/t_sin.c index a82f49dc65d6..ca581f03fad0 100644 --- a/contrib/netbsd-tests/lib/libm/t_sin.c +++ b/contrib/netbsd-tests/lib/libm/t_sin.c @@ -1,263 +1,294 @@ -/* $NetBSD: t_sin.c,v 1.4 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_sin.c,v 1.7 2019/05/27 00:24:37 maya 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 #include +#include #include static const struct { int angle; double x; double y; + float fy; } 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 } + { -360, -6.283185307179586, 2.4492935982947064e-16, -1.7484555e-07 }, + { -180, -3.141592653589793, -1.2246467991473532e-16, 8.7422777e-08 }, + { -135, -2.356194490192345, -0.7071067811865476, 999 }, + { -90, -1.570796326794897, -1.0000000000000000, 999 }, + { -45, -0.785398163397448, -0.7071067811865472, 999 }, + { 0, 0.000000000000000, 0.0000000000000000, 999 }, + { 30, 0.5235987755982989, 0.5000000000000000, 999 }, + { 45, 0.785398163397448, 0.7071067811865472, 999 }, + { 60, 1.047197551196598, 0.8660254037844388, 999 }, + { 90, 1.570796326794897, 1.0000000000000000, 999 }, + { 120, 2.094395102393195, 0.8660254037844389, 999 }, + { 135, 2.356194490192345, 0.7071067811865476, 999 }, + { 150, 2.617993877991494, 0.5000000000000003, 999 }, + { 180, 3.141592653589793, 1.2246467991473532e-16, -8.7422777e-08 }, + { 270, 4.712388980384690, -1.0000000000000000, 999 }, + { 360, 6.283185307179586, -2.4492935982947064e-16, 1.7484555e-07 }, }; /* * 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; + const double eps = DBL_EPSILON; 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); + int deg = angles[i].angle; + double theta = angles[i].x; + double sin_theta = angles[i].y; + bool ok; + + if (sin_theta == 0) { + /* Should be computed exactly. */ + assert(sin_theta == 0); + ok = (sin(theta) == 0); + } else { + assert(sin_theta != 0); + ok = (fabs((sin(theta) - sin_theta)/sin_theta) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("sin(%d deg = %.17g) = %.17g" + " != %.17g", + deg, theta, sin(theta), sin_theta); + } } } 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; + const float eps = FLT_EPSILON; 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); + int deg = angles[i].angle; + float theta = angles[i].x; + float sin_theta = angles[i].fy; + bool ok; + + if (sin_theta == 999) + sin_theta = angles[i].y; + + if (sin_theta == 0) { + /* Should be computed exactly. */ + ok = (sinf(theta) == 0); + } else { + ok = (fabsf((sinf(theta) - sin_theta)/sin_theta) + <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("sinf(%d deg) = %.8g != %.8g", + deg, sinf(theta), sin_theta); + } } } 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/contrib/netbsd-tests/lib/libm/t_sinh.c b/contrib/netbsd-tests/lib/libm/t_sinh.c index d935f0ea7ffb..d5f764fea573 100644 --- a/contrib/netbsd-tests/lib/libm/t_sinh.c +++ b/contrib/netbsd-tests/lib/libm/t_sinh.c @@ -1,273 +1,271 @@ -/* $NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_sinh.c,v 1.7 2018/11/07 03:59:36 riastradh 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 -__RCSID("$NetBSD: t_sinh.c,v 1.6 2014/03/03 10:39:08 martin Exp $"); +__RCSID("$NetBSD: t_sinh.c,v 1.7 2018/11/07 03:59:36 riastradh Exp $"); #include +#include #include #include 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, }, + { -10, -11013.232874703393, }, + { -2, -3.626860407847019, }, + { -1, -1.1752011936438014, }, + { -0.05, -0.050020835937655016, }, + { -0.001,-0.0010000001666666751, }, + { 0.001, 0.0010000001666666751, }, + { 0.05, 0.050020835937655016, }, + { 1, 1.1752011936438014, }, + { 2, 3.626860407847019, }, + { 10, 11013.232874703393, }, }; /* * 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; + const double eps = DBL_EPSILON; size_t i; for (i = 0; i < __arraycount(values); i++) { - x = values[i].x; - y = values[i].y; - eps = 1e-15 * values[i].e; + double x = values[i].x; + double sinh_x = values[i].y; - if (fabs(sinh(x) - y) > eps) - atf_tc_fail_nonfatal("sinh(%g) != %g\n", x, y); + if (!(fabs((sinh(x) - sinh_x)/sinh_x) <= eps)) { + atf_tc_fail_nonfatal("sinh(%.17g) = %.17g != %.17g\n", + x, sinh(x), sinh_x); + } } } 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; + const float eps = FLT_EPSILON; size_t i; for (i = 0; i < __arraycount(values); i++) { - x = values[i].x; - y = values[i].y; - eps = 1e-6 * values[i].e; + float x = values[i].x; + float sinh_x = values[i].y; - if (fabsf(sinhf(x) - y) > eps) - atf_tc_fail_nonfatal("sinhf(%g) != %g\n", x, y); + if (!(fabsf((sinhf(x) - sinh_x)/sinh_x) <= eps)) { + atf_tc_fail_nonfatal("sinhf(%.8g) = %.8g != %.8g\n", + (double)x, (double)sinhf(x), (double)sinh_x); + } } } 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/contrib/netbsd-tests/lib/libm/t_sqrt.c b/contrib/netbsd-tests/lib/libm/t_sqrt.c index 1d551ec3101d..080aff1c40e8 100644 --- a/contrib/netbsd-tests/lib/libm/t_sqrt.c +++ b/contrib/netbsd-tests/lib/libm/t_sqrt.c @@ -1,368 +1,386 @@ -/* $NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $ */ +/* $NetBSD: t_sqrt.c,v 1.8 2018/11/07 03:59:36 riastradh 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 -__RCSID("$NetBSD: t_sqrt.c,v 1.7 2014/03/12 21:40:07 martin Exp $"); +__RCSID("$NetBSD: t_sqrt.c,v 1.8 2018/11/07 03:59:36 riastradh Exp $"); #include #include #include #include /* * 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; + const double eps = DBL_EPSILON; 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]); + double x_sqrt = sqrt(x[i]); + double x_pow12 = pow(x[i], 1.0 / 2.0); + bool ok; + + if (x[i] == 0) { + ok = (x_sqrt == x_pow12); + } else { + ok = (fabs((x_sqrt - x_pow12)/x_sqrt) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("sqrt(%.17g) = %.17g != " + "pow(%.17g, 1/2) = %.17g\n", + x[i], x_sqrt, x[i], x_pow12); + } } } 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; + const float eps = FLT_EPSILON; 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]); + float x_sqrt = sqrtf(x[i]); + float x_pow12 = powf(x[i], 1.0 / 2.0); + bool ok; + + if (x[i] == 0) { + ok = (x_sqrt == x_pow12); + } else { + ok = (fabsf((x_sqrt - x_pow12)/x_sqrt) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("sqrtf(%.8g) = %.8g != " + "powf(%.8g, 1/2) = %.8g\n", + (double)x[i], (double)x_sqrt, + (double)x[i], (double)x_pow12); + } } } 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; + const long double eps = DBL_EPSILON; /* XXX powl == pow for now */ 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]); + long double x_sqrt = sqrtl(x[i]); + long double x_pow12 = powl(x[i], 1.0 / 2.0); + bool ok; + + if (x[i] == 0) { + ok = (x_sqrt == x_pow12); + } else { + ok = (fabsl((x_sqrt - x_pow12)/x_sqrt) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("sqrtl(%.35Lg) = %.35Lg != " + "powl(%.35Lg, 1/2) = %.35Lg\n", + x[i], x_sqrt, x[i], x_pow12); + } } } 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/contrib/netbsd-tests/lib/libm/t_tan.c b/contrib/netbsd-tests/lib/libm/t_tan.c index 807e3d1f3364..1bbc4b4d4c95 100644 --- a/contrib/netbsd-tests/lib/libm/t_tan.c +++ b/contrib/netbsd-tests/lib/libm/t_tan.c @@ -1,260 +1,292 @@ -/* $NetBSD: t_tan.c,v 1.5 2014/03/03 10:39:08 martin Exp $ */ +/* $NetBSD: t_tan.c,v 1.7 2018/11/07 04:00:13 riastradh 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 #include +#include #include static const struct { int angle; double x; double y; + float fy; } 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 } + { -180, -3.141592653589793, 1.2246467991473532e-16, -8.7422777e-08 }, + { -135, -2.356194490192345, 1.0000000000000002, 999 }, + { -45, -0.785398163397448, -0.9999999999999992, 999 }, + { 0, 0.000000000000000, 0.0000000000000000, 999 }, + { 30, 0.5235987755982988, 0.57735026918962573, 999 }, + { 45, 0.785398163397448, 0.9999999999999992, 999 }, + { 60, 1.047197551196598, 1.7320508075688785, 1.7320509 }, + { 120, 2.094395102393195, -1.7320508075688801, -1.7320505 }, + { 135, 2.356194490192345, -1.0000000000000002, 999 }, + { 150, 2.617993877991494, -0.57735026918962629, -0.57735032 }, + { 180, 3.141592653589793, -1.2246467991473532e-16, 8.7422777e-08 }, + { 360, 6.283185307179586, -2.4492935982947064e-16, 1.7484555e-07 }, }; /* * 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; + const double eps = DBL_EPSILON; 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); + int deg = angles[i].angle; + double theta = angles[i].x; + double tan_theta = angles[i].y; + bool ok; + + if (theta == 0) { + /* Should be computed exactly. */ + assert(tan_theta == 0); + ok = (tan(theta) == 0); + } else { + assert(tan_theta != 0); + ok = (fabs((tan(theta) - tan_theta)/tan_theta) <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("tan(%d deg = %.17g) = %.17g" + " != %.17g", + deg, theta, tan(theta), tan_theta); + } } } 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; + const float eps = FLT_EPSILON; 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); + int deg = angles[i].angle; + float theta = angles[i].x; + float tan_theta = angles[i].fy; + bool ok; + + if (tan_theta == 999) + tan_theta = angles[i].y; + + if (theta == 0) { + /* Should be computed exactly. */ + assert(tan_theta == 0); + ok = (tan(theta) == 0); + } else { + assert(tan_theta != 0); + ok = (fabsf((tanf(theta) - tan_theta)/tan_theta) + <= eps); + } + + if (!ok) { + atf_tc_fail_nonfatal("tanf(%d deg) = %.8g != %.8g", + deg, tanf(theta), tan_theta); + } } } 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/msun/tests/Makefile b/lib/msun/tests/Makefile index 902d1ca22f73..85a558bb0733 100644 --- a/lib/msun/tests/Makefile +++ b/lib/msun/tests/Makefile @@ -1,110 +1,112 @@ # $FreeBSD$ .include TESTSRC= ${SRCTOP}/contrib/netbsd-tests/lib/libm # All architectures on FreeBSD have fenv.h CFLAGS+= -DHAVE_FENV_H # For isqemu.h CFLAGS+= -I${TESTSRC:H}/libc/gen # Define __HAVE_LONG_DOUBLE for architectures whose long double has greater # precision than their double. .if ${MACHINE_CPUARCH} == "aarch64" || \ ${MACHINE_CPUARCH} == "amd64" || \ ${MACHINE_CPUARCH} == "i386" || \ ${MACHINE_CPUARCH} == "riscv" CFLAGS+= -D__HAVE_LONG_DOUBLE .endif # Avoid builtins, to force the compiler to emit calls to the libm # functions, and not calculate any results in advance. CFLAGS+= -fno-builtin NETBSD_ATF_TESTS_C= acos_test NETBSD_ATF_TESTS_C+= asin_test NETBSD_ATF_TESTS_C+= atan_test +NETBSD_ATF_TESTS_C+= bit_test +# TODO: NETBSD_ATF_TESTS_CXX+= cabsl_test NETBSD_ATF_TESTS_C+= cbrt_test NETBSD_ATF_TESTS_C+= ceil_test NETBSD_ATF_TESTS_C+= casinh_test NETBSD_ATF_TESTS_C+= cos_test NETBSD_ATF_TESTS_C+= cosh_test NETBSD_ATF_TESTS_C+= erf_test NETBSD_ATF_TESTS_C+= exp_test NETBSD_ATF_TESTS_C+= fmod_test NETBSD_ATF_TESTS_C+= fe_round_test NETBSD_ATF_TESTS_C+= hypot_test NETBSD_ATF_TESTS_C+= infinity_test NETBSD_ATF_TESTS_C+= ilogb_test NETBSD_ATF_TESTS_C+= ldexp_test NETBSD_ATF_TESTS_C+= log_test NETBSD_ATF_TESTS_C+= pow_test NETBSD_ATF_TESTS_C+= precision_test NETBSD_ATF_TESTS_C+= round_test NETBSD_ATF_TESTS_C+= scalbn_test NETBSD_ATF_TESTS_C+= sin_test NETBSD_ATF_TESTS_C+= sinh_test NETBSD_ATF_TESTS_C+= sqrt_test NETBSD_ATF_TESTS_C+= tan_test NETBSD_ATF_TESTS_C+= tanh_test TAP_TESTS_C+= cexp_test TAP_TESTS_C+= conj_test .if ${MACHINE_CPUARCH} != "aarch64" # Hits an assert in llvm when building for arm64: # https://llvm.org/bugs/show_bug.cgi?id=26081 TAP_TESTS_C+= csqrt_test .endif ATF_TESTS_C+= ctrig_test TAP_TESTS_C+= exponential_test TAP_TESTS_C+= fenv_test TAP_TESTS_C+= fma_test TAP_TESTS_C+= fmaxmin_test TAP_TESTS_C+= ilogb2_test TAP_TESTS_C+= invtrig_test TAP_TESTS_C+= invctrig_test TAP_TESTS_C+= logarithm_test TAP_TESTS_C+= lrint_test # XXX: the testcase crashes on all platforms, but only on head # (bug 205451) #TAP_TESTS_C+= lround_test TAP_TESTS_C+= nan_test TAP_TESTS_C+= nearbyint_test TAP_TESTS_C+= next_test TAP_TESTS_C+= rem_test ATF_TESTS_C+= trig_test .if !empty(PROG) && !empty(TAP_TESTS_C:M${PROG}) CFLAGS+= -O0 .endif #COPTS+= -Wfloat-equal IGNORE_PRAGMA= SRCS.ilogb2_test= ilogb_test.c LIBADD+= m WARNS?= 1 # Copied from lib/msun/Makefile .if ${MACHINE_CPUARCH} == "i386" ARCH_SUBDIR= i387 .else ARCH_SUBDIR= ${MACHINE_CPUARCH} .endif .include "../${ARCH_SUBDIR}/Makefile.inc" # XXX: for some odd reason float.h doesn't tell the full story about what the # precision is. CFLAGS+= -DLDBL_PREC=${LDBL_PREC} CFLAGS.fe_round_test+= -D__HAVE_FENV .include .include