diff --git a/contrib/netbsd-tests/lib/libm/t_acos.c b/contrib/netbsd-tests/lib/libm/t_acos.c --- a/contrib/netbsd-tests/lib/libm/t_acos.c +++ b/contrib/netbsd-tests/lib/libm/t_acos.c @@ -1,4 +1,4 @@ -/* $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. @@ -72,7 +72,7 @@ { 0, M_PI / 2, }, { 0.1, 1.470628905633337, }, { 0.5, 1.047197551196598, }, - { 0.99, 0.141539473324427, }, + { 0.99, 0.1415394733244273, }, }; unsigned int i; diff --git a/contrib/netbsd-tests/lib/libm/t_asin.c b/contrib/netbsd-tests/lib/libm/t_asin.c --- a/contrib/netbsd-tests/lib/libm/t_asin.c +++ b/contrib/netbsd-tests/lib/libm/t_asin.c @@ -1,4 +1,4 @@ -/* $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. @@ -30,6 +30,7 @@ */ #include +#include #include static const struct { @@ -117,13 +118,14 @@ 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); } @@ -230,16 +232,25 @@ 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(); } } diff --git a/contrib/netbsd-tests/lib/libm/t_bit.c b/contrib/netbsd-tests/lib/libm/t_bit.c new file mode 100644 --- /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 copy from contrib/netbsd-tests/lib/libm/t_fmod.c copy to contrib/netbsd-tests/lib/libm/t_cabsl.cxx --- a/contrib/netbsd-tests/lib/libm/t_fmod.c +++ b/contrib/netbsd-tests/lib/libm/t_cabsl.cxx @@ -1,11 +1,9 @@ -/* $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 @@ -29,48 +27,40 @@ * 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 --- a/contrib/netbsd-tests/lib/libm/t_cbrt.c +++ b/contrib/netbsd-tests/lib/libm/t_cbrt.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,9 +29,10 @@ * 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 @@ -61,18 +62,26 @@ 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); + } } } @@ -162,18 +171,27 @@ 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); + } } } @@ -264,27 +282,42 @@ 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); + } } } diff --git a/contrib/netbsd-tests/lib/libm/t_cos.c b/contrib/netbsd-tests/lib/libm/t_cos.c --- a/contrib/netbsd-tests/lib/libm/t_cos.c +++ b/contrib/netbsd-tests/lib/libm/t_cos.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,31 +29,138 @@ * 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) */ @@ -65,14 +172,20 @@ 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); + } } } @@ -154,18 +267,33 @@ 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); + } } } @@ -244,6 +372,14 @@ 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); diff --git a/contrib/netbsd-tests/lib/libm/t_cosh.c b/contrib/netbsd-tests/lib/libm/t_cosh.c --- a/contrib/netbsd-tests/lib/libm/t_cosh.c +++ b/contrib/netbsd-tests/lib/libm/t_cosh.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,28 +29,28 @@ * 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, }, }; /* @@ -64,18 +64,17 @@ 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); + } } } @@ -162,18 +161,17 @@ 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); + } } } diff --git a/contrib/netbsd-tests/lib/libm/t_exp.c b/contrib/netbsd-tests/lib/libm/t_exp.c --- a/contrib/netbsd-tests/lib/libm/t_exp.c +++ b/contrib/netbsd-tests/lib/libm/t_exp.c @@ -1,4 +1,4 @@ -/* $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. @@ -30,6 +30,7 @@ */ #include +#include #include #include "t_libm.h" @@ -37,17 +38,16 @@ 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, }, }; /* @@ -238,18 +238,17 @@ 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); + } } } @@ -336,18 +335,17 @@ 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); + } } } diff --git a/contrib/netbsd-tests/lib/libm/t_fe_round.c b/contrib/netbsd-tests/lib/libm/t_fe_round.c --- a/contrib/netbsd-tests/lib/libm/t_fe_round.c +++ b/contrib/netbsd-tests/lib/libm/t_fe_round.c @@ -89,7 +89,97 @@ (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); } } @@ -97,6 +187,9 @@ { 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(); } @@ -109,15 +202,56 @@ "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(); } diff --git a/contrib/netbsd-tests/lib/libm/t_fenv.c b/contrib/netbsd-tests/lib/libm/t_fenv.c --- a/contrib/netbsd-tests/lib/libm/t_fenv.c +++ b/contrib/netbsd-tests/lib/libm/t_fenv.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,7 +29,7 @@ * 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 @@ -40,15 +40,15 @@ #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. diff --git a/contrib/netbsd-tests/lib/libm/t_fmod.c b/contrib/netbsd-tests/lib/libm/t_fmod.c --- a/contrib/netbsd-tests/lib/libm/t_fmod.c +++ b/contrib/netbsd-tests/lib/libm/t_fmod.c @@ -1,4 +1,4 @@ -/* $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. @@ -50,21 +50,15 @@ 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) diff --git a/contrib/netbsd-tests/lib/libm/t_ilogb.c b/contrib/netbsd-tests/lib/libm/t_ilogb.c --- a/contrib/netbsd-tests/lib/libm/t_ilogb.c +++ b/contrib/netbsd-tests/lib/libm/t_ilogb.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,7 +29,7 @@ * 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 @@ -44,7 +44,9 @@ #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) diff --git a/contrib/netbsd-tests/lib/libm/t_ldexp.c b/contrib/netbsd-tests/lib/libm/t_ldexp.c --- a/contrib/netbsd-tests/lib/libm/t_ldexp.c +++ b/contrib/netbsd-tests/lib/libm/t_ldexp.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,14 +29,15 @@ * 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 @@ -195,22 +196,17 @@ 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]))); } } } @@ -320,18 +316,17 @@ 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]))); } } } diff --git a/contrib/netbsd-tests/lib/libm/t_libm.h b/contrib/netbsd-tests/lib/libm/t_libm.h --- a/contrib/netbsd-tests/lib/libm/t_libm.h +++ b/contrib/netbsd-tests/lib/libm/t_libm.h @@ -1,4 +1,4 @@ -/* $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. @@ -11,8 +11,8 @@ 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", \ diff --git a/contrib/netbsd-tests/lib/libm/t_log.c b/contrib/netbsd-tests/lib/libm/t_log.c --- a/contrib/netbsd-tests/lib/libm/t_log.c +++ b/contrib/netbsd-tests/lib/libm/t_log.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,10 +29,11 @@ * 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 @@ -614,10 +615,10 @@ 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); @@ -714,10 +715,11 @@ 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); diff --git a/contrib/netbsd-tests/lib/libm/t_round.c b/contrib/netbsd-tests/lib/libm/t_round.c --- a/contrib/netbsd-tests/lib/libm/t_round.c +++ b/contrib/netbsd-tests/lib/libm/t_round.c @@ -1,4 +1,4 @@ -/* $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. @@ -26,9 +26,14 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include + #include #include #include +#include +#include +#include /* * This tests for a bug in the initial implementation where @@ -76,10 +81,58 @@ 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 --- a/contrib/netbsd-tests/lib/libm/t_scalbn.c +++ b/contrib/netbsd-tests/lib/libm/t_scalbn.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,12 +29,13 @@ * 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 @@ -46,16 +47,17 @@ 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 @@ -82,13 +84,25 @@ 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)); } } @@ -228,9 +242,12 @@ 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)); } } @@ -373,9 +390,12 @@ 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 } diff --git a/contrib/netbsd-tests/lib/libm/t_sin.c b/contrib/netbsd-tests/lib/libm/t_sin.c --- a/contrib/netbsd-tests/lib/libm/t_sin.c +++ b/contrib/netbsd-tests/lib/libm/t_sin.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,29 +29,33 @@ * 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 }, }; /* @@ -65,14 +69,29 @@ 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); + } } } @@ -154,18 +173,30 @@ 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); + } } } diff --git a/contrib/netbsd-tests/lib/libm/t_sinh.c b/contrib/netbsd-tests/lib/libm/t_sinh.c --- a/contrib/netbsd-tests/lib/libm/t_sinh.c +++ b/contrib/netbsd-tests/lib/libm/t_sinh.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,27 +29,27 @@ * 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, }, }; /* @@ -63,18 +63,17 @@ 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); + } } } @@ -163,18 +162,17 @@ 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); + } } } diff --git a/contrib/netbsd-tests/lib/libm/t_sqrt.c b/contrib/netbsd-tests/lib/libm/t_sqrt.c --- a/contrib/netbsd-tests/lib/libm/t_sqrt.c +++ b/contrib/netbsd-tests/lib/libm/t_sqrt.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,7 +29,7 @@ * 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 @@ -62,22 +62,25 @@ 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); + } } } @@ -166,18 +169,26 @@ 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); + } } } @@ -266,18 +277,25 @@ 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); + } } } diff --git a/contrib/netbsd-tests/lib/libm/t_tan.c b/contrib/netbsd-tests/lib/libm/t_tan.c --- a/contrib/netbsd-tests/lib/libm/t_tan.c +++ b/contrib/netbsd-tests/lib/libm/t_tan.c @@ -1,4 +1,4 @@ -/* $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. @@ -29,26 +29,29 @@ * 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 }, }; /* @@ -62,14 +65,29 @@ 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); + } } } @@ -151,18 +169,32 @@ 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); + } } } diff --git a/lib/msun/tests/Makefile b/lib/msun/tests/Makefile --- a/lib/msun/tests/Makefile +++ b/lib/msun/tests/Makefile @@ -22,6 +22,8 @@ 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