From bcd5ff3f40ada32d54ec110b6d0db0c5a7829f92 Mon Sep 17 00:00:00 2001 From: Rafal Walczyna Date: Tue, 21 Apr 2020 12:34:38 +0200 Subject: [PATCH] Implement missing hyperbolic Math functions from ES6 (#3670) Math.cosh, Math.sinh, Math.tanh C implementation ported from fdlibm. Part of Issue #3568 JerryScript-DCO-1.0-Signed-off-by: Rafal Walczyna r.walczyna@samsung.com --- .../ecma/builtin-objects/ecma-builtin-math.c | 12 -- jerry-libm/cosh.c | 113 ++++++++++++++ jerry-libm/include/math.h | 5 + jerry-libm/jerry-libm-internal.h | 4 + jerry-libm/sinh.c | 115 ++++++++++++++ jerry-libm/tanh.c | 117 ++++++++++++++ tests/jerry/es2015/math-cosh.js | 22 +++ tests/jerry/es2015/math-sinh.js | 27 ++++ tests/jerry/es2015/math-tanh.js | 27 ++++ tests/unit-libm/test-libm.inc.h | 141 +++++++++++++++++ tools/unit-tests/gen-test-libm.c | 147 ++++++++++++++++++ 11 files changed, 718 insertions(+), 12 deletions(-) create mode 100644 jerry-libm/cosh.c create mode 100644 jerry-libm/sinh.c create mode 100644 jerry-libm/tanh.c create mode 100644 tests/jerry/es2015/math-cosh.js create mode 100644 tests/jerry/es2015/math-sinh.js create mode 100644 tests/jerry/es2015/math-tanh.js diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-math.c b/jerry-core/ecma/builtin-objects/ecma-builtin-math.c index 9c389baec..28bc44b1c 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-math.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-math.c @@ -545,11 +545,7 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w } case ECMA_MATH_OBJECT_COSH: { -#ifdef JERRY_LIBM_MATH_H - return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Math.cosh")); -#else /* !JERRY_LIBM_MATH_H */ x = DOUBLE_TO_ECMA_NUMBER_T (cosh (x)); -#endif /* JERRY_LIBM_MATH_H */ break; } case ECMA_MATH_OBJECT_EXPM1: @@ -574,20 +570,12 @@ ecma_builtin_math_dispatch_routine (uint16_t builtin_routine_id, /**< built-in w } case ECMA_MATH_OBJECT_SINH: { -#ifdef JERRY_LIBM_MATH_H - return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Math.sinh")); -#else /* !JERRY_LIBM_MATH_H */ x = DOUBLE_TO_ECMA_NUMBER_T (sinh (x)); -#endif /* JERRY_LIBM_MATH_H */ break; } case ECMA_MATH_OBJECT_TANH: { -#ifdef JERRY_LIBM_MATH_H - return ecma_raise_type_error (ECMA_ERR_MSG ("UNIMPLEMENTED: Math.tanh")); -#else /* !JERRY_LIBM_MATH_H */ x = DOUBLE_TO_ECMA_NUMBER_T (tanh (x)); -#endif /* JERRY_LIBM_MATH_H */ break; } case ECMA_MATH_OBJECT_CLZ32: diff --git a/jerry-libm/cosh.c b/jerry-libm/cosh.c new file mode 100644 index 000000000..c21297b9b --- /dev/null +++ b/jerry-libm/cosh.c @@ -0,0 +1,113 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is based on work under the following copyright and permission + * notice: + * + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * + * @(#)e_cosh.c 1.3 95/01/18 + */ + +#include "jerry-libm-internal.h" + +/* cosh(x) + * Method: + * mathematically cosh(x) if defined to be (exp(x) + exp(-x)) / 2 + * 1. Replace x by |x| (cosh(x) = cosh(-x)). + * 2. + * [ exp(x) - 1 ]^2 + * 0 <= x <= ln2/2 : cosh(x) := 1 + ------------------- + * 2*exp(x) + * + * exp(x) + 1/exp(x) + * ln2/2 <= x <= 22 : cosh(x) := ------------------- + * 2 + * + * 22 <= x <= lnovft : cosh(x) := exp(x)/2 + * lnovft <= x <= ln2ovft: cosh(x) := exp(x/2)/2 * exp(x/2) + * ln2ovft < x : cosh(x) := huge * huge (overflow) + * + * Special cases: + * cosh(x) is |x| if x is +INF, -INF, or NaN. + * only cosh(0) = 1 is exact for finite x. + */ + +#define one 1.0 +#define half 0.5 +#define huge 1.0e300 + +double +cosh (double x) +{ + double t, w; + int ix; + unsigned lx; + + /* High word of |x|. */ + ix = __HI (x); + ix &= 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) + { + return x * x; + } + /* |x| in [0, 0.5 * ln2], return 1 + expm1(|x|)^2 / (2 * exp(|x|)) */ + if (ix < 0x3fd62e43) + { + t = expm1 (fabs (x)); + w = one + t; + if (ix < 0x3c800000) + { + /* cosh(tiny) = 1 */ + return w; + } + return one + (t * t) / (w + w); + } + + /* |x| in [0.5 * ln2, 22], return (exp(|x|) + 1 / exp(|x|) / 2; */ + if (ix < 0x40360000) + { + t = exp (fabs (x)); + return half * t + half / t; + } + + /* |x| in [22, log(maxdouble)] return half * exp(|x|) */ + if (ix < 0x40862E42) + { + return half * exp (fabs (x)); + } + /* |x| in [log(maxdouble), overflowthresold] */ + lx = ((1 >> 29) + (unsigned int) x); + if ((ix < 0x408633CE) || + ((ix == 0x408633ce) && (lx <= (unsigned) 0x8fb9f87d))) + { + w = exp (half * fabs (x)); + t = half * w; + return t * w; + } + + /* |x| > overflowthresold, cosh(x) overflow */ + return huge * huge; +} /* cosh */ + +#undef one +#undef half +#undef huge diff --git a/jerry-libm/include/math.h b/jerry-libm/include/math.h index 71d778eef..9a0a682f7 100644 --- a/jerry-libm/include/math.h +++ b/jerry-libm/include/math.h @@ -56,6 +56,11 @@ double asin (double); double atan (double); double atan2 (double, double); +/* Hyperbolic functions. */ +double cosh (double x); +double sinh (double x); +double tanh (double x); + /* Inverse hyperbolic functions */ double acosh (double); double asinh (double); diff --git a/jerry-libm/jerry-libm-internal.h b/jerry-libm/jerry-libm-internal.h index b87519200..d03e63d58 100644 --- a/jerry-libm/jerry-libm-internal.h +++ b/jerry-libm/jerry-libm-internal.h @@ -88,6 +88,10 @@ double cos (double x); double sin (double x); double tan (double x); +double cosh (double x); +double sinh (double x); +double tanh (double x); + double acosh (double x); double asinh (double x); double atanh (double x); diff --git a/jerry-libm/sinh.c b/jerry-libm/sinh.c new file mode 100644 index 000000000..5439c3a5d --- /dev/null +++ b/jerry-libm/sinh.c @@ -0,0 +1,115 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is based on work under the following copyright and permission + * notice: + * + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * + * @(#)e_sinh.c 1.3 95/01/18 + */ + +#include "jerry-libm-internal.h" + +/* __sinh(x) + * Method: + * mathematically sinh(x) if defined to be (exp(x) - exp(-x)) / 2 + * 1. Replace x by |x| (sinh(-x) = -sinh(x)). + * 2. + * E + E/(E+1) + * 0 <= x <= 22 : sinh(x) := -------------, E = expm1(x) + * 2 + * + * 22 <= x <= lnovft : sinh(x) := exp(x) / 2 + * lnovft <= x <= ln2ovft: sinh(x) := exp(x / 2) / 2 * exp(x / 2) + * ln2ovft < x : sinh(x) := x * shuge (overflow) + * + * Special cases: + * sinh(x) is |x| if x is +INF, -INF, or NaN. + * only sinh(0) = 0 is exact for finite x. + */ + +#define one 1.0 +#define half 0.5 +#define shuge 1.0e307 + +double +sinh (double x) +{ + double t, w, h; + int ix, jx; + unsigned lx; + + /* High word of |x|. */ + jx = __HI (x); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) + { + return x + x; + } + + h = 0.5; + if (jx < 0) + { + h = -h; + } + /* |x| in [0,22], return sign(x) * 0.5 * (E + E / (E + 1))) */ + if (ix < 0x40360000) + { + /* |x| < 22 */ + if (ix < 0x3e300000) + { + /* |x| < 2**-28 */ + if (shuge + x > one) + { + /* sinh(tiny) = tiny with inexact */ + return x; + } + } + t = expm1 (fabs (x)); + if (ix < 0x3ff00000) + { + return h * (2.0 * t - t * t / (t + one)); + } + return h * (t + t / (t + one)); + } + + /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */ + if (ix < 0x40862E42) + { + return h * exp (fabs (x)); + } + /* |x| in [log(maxdouble), overflowthresold] */ + lx = ((1 >> 29) + (unsigned int) x); + if (ix < 0x408633CE || ((ix == 0x408633ce) && (lx <= (unsigned) 0x8fb9f87d))) + { + w = exp (0.5 * fabs (x)); + t = h * w; + return t * w; + } + + /* |x| > overflowthresold, sinh(x) overflow */ + return x * shuge; +} /* sinh */ + +#undef one +#undef half +#undef huge diff --git a/jerry-libm/tanh.c b/jerry-libm/tanh.c new file mode 100644 index 000000000..b7ab527f5 --- /dev/null +++ b/jerry-libm/tanh.c @@ -0,0 +1,117 @@ +/* Copyright JS Foundation and other contributors, http://js.foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * This file is based on work under the following copyright and permission + * notice: + * + * Copyright (C) 1993 by Sun Microsystems, Inc. All rights reserved. + * + * Developed at SunSoft, a Sun Microsystems, Inc. business. + * Permission to use, copy, modify, and distribute this + * software is freely granted, provided that this notice + * is preserved. + * + * @(#)s_tanh.c 1.3 95/01/18 + */ + +#include "jerry-libm-internal.h" + +/* tanh(x) + * Return the Hyperbolic Tangent of x + * + * Method: + * x -x + * e - e + * 0. tanh(x) is defined to be ----------- + * x -x + * e + e + * + * 1. reduce x to non-negative by tanh(-x) = -tanh(x). + * 2. 0 <= x <= 2**-55 : tanh(x) := x * (one + x) + * + * -t + * 2**-55 < x <= 1 : tanh(x) := -----; t = expm1(-2x) + * t + 2 + * + * 2 + * 1 <= x <= 22.0 : tanh(x) := 1- ----- ; t = expm1(2x) + * t + 2 + * + * 22.0 < x <= INF : tanh(x) := 1. + * + * Special cases: + * tanh(NaN) is NaN; + * only tanh(0) = 0 is exact for finite x. + */ +#define one 1.0 +#define two 2.0 +#define tiny 1.0e-300 + +double +tanh (double x) +{ + double t, z; + int jx, ix; + + /* High word of |x|. */ + jx = __HI (x); + ix = jx & 0x7fffffff; + + /* x is INF or NaN */ + if (ix >= 0x7ff00000) + { + if (jx >= 0) + { + /* tanh(+-inf) = +-1 */ + return one / x + one; + } + else + { + /* tanh(NaN) = NaN */ + return one / x - one; + } + } + + /* |x| < 22 */ + if (ix < 0x40360000) + { + /* |x| < 2**-55 */ + if (ix < 0x3c800000) + { + /* tanh(small) = small */ + return x * (one + x); + } + if (ix >= 0x3ff00000) + { + /* |x| >= 1 */ + t = expm1 (two * fabs (x)); + z = one - two / (t + two); + } + else + { + t = expm1 (-two * fabs (x)); + z = -t / (t + two); + } + } + else + { + /* |x| > 22, return +-1 */ + z = one - tiny; /* raised inexact flag */ + } + return (jx >= 0) ? z : -z; +} /* tanh */ + +#undef one +#undef two +#undef tiny diff --git a/tests/jerry/es2015/math-cosh.js b/tests/jerry/es2015/math-cosh.js new file mode 100644 index 000000000..f68e4cb46 --- /dev/null +++ b/tests/jerry/es2015/math-cosh.js @@ -0,0 +1,22 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var p_zero = 0.0; +var n_zero = -p_zero; + +assert(isNaN(Math.cosh(NaN))); +assert(Math.cosh(p_zero) === 1); +assert(Math.cosh(n_zero) === 1); +assert(Math.cosh(Number.POSITIVE_INFINITY) === Number.POSITIVE_INFINITY); +assert(Math.cosh(Number.NEGATIVE_INFINITY) === Number.POSITIVE_INFINITY); diff --git a/tests/jerry/es2015/math-sinh.js b/tests/jerry/es2015/math-sinh.js new file mode 100644 index 000000000..e6a4137e6 --- /dev/null +++ b/tests/jerry/es2015/math-sinh.js @@ -0,0 +1,27 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var p_zero = 0.0; +var n_zero = -p_zero; + +function isSameZero (x, y) +{ + return x === 0 && (1 / x) === (1 / y); +} + +assert(isNaN(Math.sinh(NaN))); +assert(isSameZero(Math.sinh(p_zero), p_zero)); +assert(isSameZero(Math.sinh(n_zero), n_zero)); +assert(Math.sinh(Number.POSITIVE_INFINITY) === Number.POSITIVE_INFINITY); +assert(Math.sinh(Number.NEGATIVE_INFINITY) === Number.NEGATIVE_INFINITY); diff --git a/tests/jerry/es2015/math-tanh.js b/tests/jerry/es2015/math-tanh.js new file mode 100644 index 000000000..26872cc12 --- /dev/null +++ b/tests/jerry/es2015/math-tanh.js @@ -0,0 +1,27 @@ +// Copyright JS Foundation and other contributors, http://js.foundation +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +var p_zero = 0.0; +var n_zero = -p_zero; + +function isSameZero (x, y) +{ + return x === 0 && (1 / x) === (1 / y); +} + +assert(isNaN(Math.tanh(NaN))); +assert(isSameZero(Math.tanh(p_zero), p_zero)); +assert(isSameZero(Math.tanh(n_zero), n_zero)); +assert(Math.tanh(Number.POSITIVE_INFINITY) === 1); +assert(Math.tanh(Number.NEGATIVE_INFINITY) === -1); diff --git a/tests/unit-libm/test-libm.inc.h b/tests/unit-libm/test-libm.inc.h index 48bd7f764..7cb03c0c1 100644 --- a/tests/unit-libm/test-libm.inc.h +++ b/tests/unit-libm/test-libm.inc.h @@ -768,3 +768,144 @@ check_double ("tan (6.0)", tan (6.0), -2.91006191384749146600E-01); check_double ("tan (-6.0)", tan (-6.0), 2.91006191384749146600E-01); check_double ("tan (7.0)", tan (7.0), 8.71447982724318781500E-01); check_double ("tan (-7.0)", tan (-7.0), -8.71447982724318781500E-01); +check_double ("cosh (0.0)", cosh (0.0), 1.00000000000000000000E+00); +check_double ("cosh (-0.0)", cosh (-0.0), 1.00000000000000000000E+00); +check_double ("cosh (1.0)", cosh (1.0), 1.54308063481524371241E+00); +check_double ("cosh (-1.0)", cosh (-1.0), 1.54308063481524371241E+00); +check_double ("cosh (INFINITY)", cosh (INFINITY), INF); +check_double ("cosh (-INFINITY)", cosh (-INFINITY), INF); +check_double ("cosh (NAN)", cosh (NAN), NAN); +check_double ("cosh (M_PI)", cosh (M_PI), 1.15919532755215186626E+01); +check_double ("cosh (-M_PI)", cosh (-M_PI), 1.15919532755215186626E+01); +check_double ("cosh (2.0 * M_PI)", cosh (2.0 * M_PI), 2.67746761483748173305E+02); +check_double ("cosh (-2.0 * M_PI)", cosh (-2.0 * M_PI), 2.67746761483748173305E+02); +check_double ("cosh (M_PI / 2.0)", cosh (M_PI / 2.0), 2.50917847865805665464E+00); +check_double ("cosh (-M_PI / 2.0)", cosh (-M_PI / 2.0), 2.50917847865805665464E+00); +check_double ("cosh (M_PI / 3.0)", cosh (M_PI / 3.0), 1.60028685770238610075E+00); +check_double ("cosh (-M_PI / 3.0)", cosh (-M_PI / 3.0), 1.60028685770238610075E+00); +check_double ("cosh (M_PI / 4.0)", cosh (M_PI / 4.0), 1.32460908925200571140E+00); +check_double ("cosh (-M_PI / 4.0)", cosh (-M_PI / 4.0), 1.32460908925200571140E+00); +check_double ("cosh (M_PI / 6.0)", cosh (M_PI / 6.0), 1.14023832107642886236E+00); +check_double ("cosh (-M_PI / 6.0)", cosh (-M_PI / 6.0), 1.14023832107642886236E+00); +check_double ("cosh (M_PI * 2.0 / 3.0)", cosh (M_PI * 2.0 / 3.0), 4.12183605386995388642E+00); +check_double ("cosh (-M_PI * 2.0 / 3.0)", cosh (-M_PI * 2.0 / 3.0), 4.12183605386995388642E+00); +check_double ("cosh (M_PI * 5.0 / 6.0)", cosh (M_PI * 5.0 / 6.0), 6.89057236497588299073E+00); +check_double ("cosh (-M_PI * 5.0 / 6.0)", cosh (-M_PI * 5.0 / 6.0), 6.89057236497588299073E+00); +check_double ("cosh (6.9e-18)", cosh (6.9e-18), 1.00000000000000000000E+00); +check_double ("cosh (-6.9e-18)", cosh (-6.9e-18), 1.00000000000000000000E+00); +check_double ("cosh (7.0e-18)", cosh (7.0e-18), 1.00000000000000000000E+00); +check_double ("cosh (-7.0e-18)", cosh (-7.0e-18), 1.00000000000000000000E+00); +check_double ("cosh (7.4e-9)", cosh (7.4e-9), 1.00000000000000000000E+00); +check_double ("cosh (-7.4e-9)", cosh (-7.4e-9), 1.00000000000000000000E+00); +check_double ("cosh (7.5e-9)", cosh (7.5e-9), 1.00000000000000000000E+00); +check_double ("cosh (-7.5e-9)", cosh (-7.5e-9), 1.00000000000000000000E+00); +check_double ("cosh (0.2)", cosh (0.2), 1.02006675561907589334E+00); +check_double ("cosh (-0.2)", cosh (-0.2), 1.02006675561907589334E+00); +check_double ("cosh (0.4)", cosh (0.4), 1.08107237183845472650E+00); +check_double ("cosh (-0.4)", cosh (-0.4), 1.08107237183845472650E+00); +check_double ("cosh (0.7)", cosh (0.7), 1.25516900563094302434E+00); +check_double ("cosh (-0.7)", cosh (-0.7), 1.25516900563094302434E+00); +check_double ("cosh (0.8)", cosh (0.8), 1.33743494630484471841E+00); +check_double ("cosh (-0.8)", cosh (-0.8), 1.33743494630484471841E+00); +check_double ("cosh (3.0)", cosh (3.0), 1.00676619957777653269E+01); +check_double ("cosh (-3.0)", cosh (-3.0), 1.00676619957777653269E+01); +check_double ("cosh (4.0)", cosh (4.0), 2.73082328360164865444E+01); +check_double ("cosh (-4.0)", cosh (-4.0), 2.73082328360164865444E+01); +check_double ("cosh (6.0)", cosh (6.0), 2.01715636122455890700E+02); +check_double ("cosh (-6.0)", cosh (-6.0), 2.01715636122455890700E+02); +check_double ("cosh (7.0)", cosh (7.0), 5.48317035155212124664E+02); +check_double ("cosh (-7.0)", cosh (-7.0), 5.48317035155212124664E+02); +check_double ("sinh (0.0)", sinh (0.0), 0.00000000000000000000E+00); +check_double ("sinh (-0.0)", sinh (-0.0), -0.00000000000000000000E+00); +check_double ("sinh (1.0)", sinh (1.0), 1.17520119364380137839E+00); +check_double ("sinh (-1.0)", sinh (-1.0), -1.17520119364380137839E+00); +check_double ("sinh (INFINITY)", sinh (INFINITY), INF); +check_double ("sinh (-INFINITY)", sinh (-INFINITY), -INF); +check_double ("sinh (NAN)", sinh (NAN), NAN); +check_double ("sinh (M_PI)", sinh (M_PI), 1.15487393572577463630E+01); +check_double ("sinh (-M_PI)", sinh (-M_PI), -1.15487393572577463630E+01); +check_double ("sinh (2.0 * M_PI)", sinh (2.0 * M_PI), 2.67744894041016436859E+02); +check_double ("sinh (-2.0 * M_PI)", sinh (-2.0 * M_PI), -2.67744894041016436859E+02); +check_double ("sinh (M_PI / 2.0)", sinh (M_PI / 2.0), 2.30129890230729472478E+00); +check_double ("sinh (-M_PI / 2.0)", sinh (-M_PI / 2.0), -2.30129890230729472478E+00); +check_double ("sinh (M_PI / 3.0)", sinh (M_PI / 3.0), 1.24936705052397512006E+00); +check_double ("sinh (-M_PI / 3.0)", sinh (-M_PI / 3.0), -1.24936705052397512006E+00); +check_double ("sinh (M_PI / 4.0)", sinh (M_PI / 4.0), 8.68670961486009529651E-01); +check_double ("sinh (-M_PI / 4.0)", sinh (-M_PI / 4.0), -8.68670961486009529651E-01); +check_double ("sinh (M_PI / 6.0)", sinh (M_PI / 6.0), 5.47853473888039732564E-01); +check_double ("sinh (-M_PI / 6.0)", sinh (-M_PI / 6.0), -5.47853473888039732564E-01); +check_double ("sinh (M_PI * 2.0 / 3.0)", sinh (M_PI * 2.0 / 3.0), 3.99869134279982052504E+00); +check_double ("sinh (-M_PI * 2.0 / 3.0)", sinh (-M_PI * 2.0 / 3.0), -3.99869134279982052504E+00); +check_double ("sinh (M_PI * 5.0 / 6.0)", sinh (M_PI * 5.0 / 6.0), 6.81762330412654371514E+00); +check_double ("sinh (-M_PI * 5.0 / 6.0)", sinh (-M_PI * 5.0 / 6.0), -6.81762330412654371514E+00); +check_double ("sinh (6.9e-18)", sinh (6.9e-18), 6.90000000000000026253E-18); +check_double ("sinh (-6.9e-18)", sinh (-6.9e-18), -6.90000000000000026253E-18); +check_double ("sinh (7.0e-18)", sinh (7.0e-18), 6.99999999999999973042E-18); +check_double ("sinh (-7.0e-18)", sinh (-7.0e-18), -6.99999999999999973042E-18); +check_double ("sinh (7.4e-9)", sinh (7.4e-9), 7.40000000000000008865E-09); +check_double ("sinh (-7.4e-9)", sinh (-7.4e-9), -7.40000000000000008865E-09); +check_double ("sinh (7.5e-9)", sinh (7.5e-9), 7.49999999999999932974E-09); +check_double ("sinh (-7.5e-9)", sinh (-7.5e-9), -7.49999999999999932974E-09); +check_double ("sinh (0.2)", sinh (0.2), 2.01336002541093989082E-01); +check_double ("sinh (-0.2)", sinh (-0.2), -2.01336002541093989082E-01); +check_double ("sinh (0.4)", sinh (0.4), 4.10752325802815509981E-01); +check_double ("sinh (-0.4)", sinh (-0.4), -4.10752325802815509981E-01); +check_double ("sinh (0.7)", sinh (0.7), 7.58583701839533497413E-01); +check_double ("sinh (-0.7)", sinh (-0.7), -7.58583701839533497413E-01); +check_double ("sinh (0.8)", sinh (0.8), 8.88105982187623044233E-01); +check_double ("sinh (-0.8)", sinh (-0.8), -8.88105982187623044233E-01); +check_double ("sinh (3.0)", sinh (3.0), 1.00178749274099025968E+01); +check_double ("sinh (-3.0)", sinh (-3.0), -1.00178749274099025968E+01); +check_double ("sinh (4.0)", sinh (4.0), 2.72899171971277532123E+01); +check_double ("sinh (-4.0)", sinh (-4.0), -2.72899171971277532123E+01); +check_double ("sinh (6.0)", sinh (6.0), 2.01713157370279219549E+02); +check_double ("sinh (-6.0)", sinh (-6.0), -2.01713157370279219549E+02); +check_double ("sinh (7.0)", sinh (7.0), 5.48316123273246489589E+02); +check_double ("sinh (-7.0)", sinh (-7.0), -5.48316123273246489589E+02); +check_double ("tanh (0.0)", tanh (0.0), 0.00000000000000000000E+00); +check_double ("tanh (-0.0)", tanh (-0.0), -0.00000000000000000000E+00); +check_double ("tanh (1.0)", tanh (1.0), 7.61594155955764851029E-01); +check_double ("tanh (-1.0)", tanh (-1.0), -7.61594155955764851029E-01); +check_double ("tanh (INFINITY)", tanh (INFINITY), 1.00000000000000000000E+00); +check_double ("tanh (-INFINITY)", tanh (-INFINITY), -1.00000000000000000000E+00); +check_double ("tanh (NAN)", tanh (NAN), NAN); +check_double ("tanh (M_PI)", tanh (M_PI), 9.96272076220749980280E-01); +check_double ("tanh (-M_PI)", tanh (-M_PI), -9.96272076220749980280E-01); +check_double ("tanh (2.0 * M_PI)", tanh (2.0 * M_PI), 9.99993025339610652757E-01); +check_double ("tanh (-2.0 * M_PI)", tanh (-2.0 * M_PI), -9.99993025339610652757E-01); +check_double ("tanh (M_PI / 2.0)", tanh (M_PI / 2.0), 9.17152335667274387632E-01); +check_double ("tanh (-M_PI / 2.0)", tanh (-M_PI / 2.0), -9.17152335667274387632E-01); +check_double ("tanh (M_PI / 3.0)", tanh (M_PI / 3.0), 7.80714435359267655556E-01); +check_double ("tanh (-M_PI / 3.0)", tanh (-M_PI / 3.0), -7.80714435359267655556E-01); +check_double ("tanh (M_PI / 4.0)", tanh (M_PI / 4.0), 6.55794202632672407205E-01); +check_double ("tanh (-M_PI / 4.0)", tanh (-M_PI / 4.0), -6.55794202632672407205E-01); +check_double ("tanh (M_PI / 6.0)", tanh (M_PI / 6.0), 4.80472778156451563181E-01); +check_double ("tanh (-M_PI / 6.0)", tanh (-M_PI / 6.0), -4.80472778156451563181E-01); +check_double ("tanh (M_PI * 2.0 / 3.0)", tanh (M_PI * 2.0 / 3.0), 9.70123821165930766419E-01); +check_double ("tanh (-M_PI * 2.0 / 3.0)", tanh (-M_PI * 2.0 / 3.0), -9.70123821165930766419E-01); +check_double ("tanh (M_PI * 5.0 / 6.0)", tanh (M_PI * 5.0 / 6.0), 9.89413207352682011475E-01); +check_double ("tanh (-M_PI * 5.0 / 6.0)", tanh (-M_PI * 5.0 / 6.0), -9.89413207352682011475E-01); +check_double ("tanh (6.9e-18)", tanh (6.9e-18), 6.90000000000000026253E-18); +check_double ("tanh (-6.9e-18)", tanh (-6.9e-18), -6.90000000000000026253E-18); +check_double ("tanh (7.0e-18)", tanh (7.0e-18), 6.99999999999999973042E-18); +check_double ("tanh (-7.0e-18)", tanh (-7.0e-18), -6.99999999999999973042E-18); +check_double ("tanh (7.4e-9)", tanh (7.4e-9), 7.40000000000000008865E-09); +check_double ("tanh (-7.4e-9)", tanh (-7.4e-9), -7.40000000000000008865E-09); +check_double ("tanh (7.5e-9)", tanh (7.5e-9), 7.49999999999999932974E-09); +check_double ("tanh (-7.5e-9)", tanh (-7.5e-9), -7.49999999999999932974E-09); +check_double ("tanh (0.2)", tanh (0.2), 1.97375320224904005073E-01); +check_double ("tanh (-0.2)", tanh (-0.2), -1.97375320224904005073E-01); +check_double ("tanh (0.4)", tanh (0.4), 3.79948962255224897966E-01); +check_double ("tanh (-0.4)", tanh (-0.4), -3.79948962255224897966E-01); +check_double ("tanh (0.7)", tanh (0.7), 6.04367777117163496037E-01); +check_double ("tanh (-0.7)", tanh (-0.7), -6.04367777117163496037E-01); +check_double ("tanh (0.8)", tanh (0.8), 6.64036770267849019156E-01); +check_double ("tanh (-0.8)", tanh (-0.8), -6.64036770267849019156E-01); +check_double ("tanh (3.0)", tanh (3.0), 9.95054753686730464324E-01); +check_double ("tanh (-3.0)", tanh (-3.0), -9.95054753686730464324E-01); +check_double ("tanh (4.0)", tanh (4.0), 9.99329299739067034025E-01); +check_double ("tanh (-4.0)", tanh (-4.0), -9.99329299739067034025E-01); +check_double ("tanh (6.0)", tanh (6.0), 9.99987711650795585427E-01); +check_double ("tanh (-6.0)", tanh (-6.0), -9.99987711650795585427E-01); +check_double ("tanh (7.0)", tanh (7.0), 9.99998336943944687860E-01); +check_double ("tanh (-7.0)", tanh (-7.0), -9.99998336943944687860E-01); diff --git a/tools/unit-tests/gen-test-libm.c b/tools/unit-tests/gen-test-libm.c index 19ca411e1..3ee4f00e7 100644 --- a/tools/unit-tests/gen-test-libm.c +++ b/tools/unit-tests/gen-test-libm.c @@ -967,4 +967,151 @@ main (int argc, char **args) GEN_DBL_TEST (tan (-6.0)); GEN_DBL_TEST (tan (7.0)); GEN_DBL_TEST (tan (-7.0)); + + /* cosh tests */ + GEN_DBL_TEST (cosh (0.0)); + GEN_DBL_TEST (cosh (-0.0)); + GEN_DBL_TEST (cosh (1.0)); + GEN_DBL_TEST (cosh (-1.0)); + GEN_DBL_TEST (cosh (INFINITY)); + GEN_DBL_TEST (cosh (-INFINITY)); + GEN_DBL_TEST (cosh (NAN)); + GEN_DBL_TEST (cosh (M_PI)); + GEN_DBL_TEST (cosh (-M_PI)); + GEN_DBL_TEST (cosh (2.0 * M_PI)); + GEN_DBL_TEST (cosh (-2.0 * M_PI)); + GEN_DBL_TEST (cosh (M_PI / 2.0)); + GEN_DBL_TEST (cosh (-M_PI / 2.0)); + GEN_DBL_TEST (cosh (M_PI / 3.0)); + GEN_DBL_TEST (cosh (-M_PI / 3.0)); + GEN_DBL_TEST (cosh (M_PI / 4.0)); + GEN_DBL_TEST (cosh (-M_PI / 4.0)); + GEN_DBL_TEST (cosh (M_PI / 6.0)); + GEN_DBL_TEST (cosh (-M_PI / 6.0)); + GEN_DBL_TEST (cosh (M_PI * 2.0 / 3.0)); + GEN_DBL_TEST (cosh (-M_PI * 2.0 / 3.0)); + GEN_DBL_TEST (cosh (M_PI * 5.0 / 6.0)); + GEN_DBL_TEST (cosh (-M_PI * 5.0 / 6.0)); + GEN_DBL_TEST (cosh (6.9e-18)); + GEN_DBL_TEST (cosh (-6.9e-18)); + GEN_DBL_TEST (cosh (7.0e-18)); + GEN_DBL_TEST (cosh (-7.0e-18)); + GEN_DBL_TEST (cosh (7.4e-9)); + GEN_DBL_TEST (cosh (-7.4e-9)); + GEN_DBL_TEST (cosh (7.5e-9)); + GEN_DBL_TEST (cosh (-7.5e-9)); + GEN_DBL_TEST (cosh (0.2)); + GEN_DBL_TEST (cosh (-0.2)); + GEN_DBL_TEST (cosh (0.4)); + GEN_DBL_TEST (cosh (-0.4)); + GEN_DBL_TEST (cosh (0.7)); + GEN_DBL_TEST (cosh (-0.7)); + GEN_DBL_TEST (cosh (0.8)); + GEN_DBL_TEST (cosh (-0.8)); + GEN_DBL_TEST (cosh (3.0)); + GEN_DBL_TEST (cosh (-3.0)); + GEN_DBL_TEST (cosh (4.0)); + GEN_DBL_TEST (cosh (-4.0)); + GEN_DBL_TEST (cosh (6.0)); + GEN_DBL_TEST (cosh (-6.0)); + GEN_DBL_TEST (cosh (7.0)); + GEN_DBL_TEST (cosh (-7.0)); + + /* sinh tests */ + GEN_DBL_TEST (sinh (0.0)); + GEN_DBL_TEST (sinh (-0.0)); + GEN_DBL_TEST (sinh (1.0)); + GEN_DBL_TEST (sinh (-1.0)); + GEN_DBL_TEST (sinh (INFINITY)); + GEN_DBL_TEST (sinh (-INFINITY)); + GEN_DBL_TEST (sinh (NAN)); + GEN_DBL_TEST (sinh (M_PI)); + GEN_DBL_TEST (sinh (-M_PI)); + GEN_DBL_TEST (sinh (2.0 * M_PI)); + GEN_DBL_TEST (sinh (-2.0 * M_PI)); + GEN_DBL_TEST (sinh (M_PI / 2.0)); + GEN_DBL_TEST (sinh (-M_PI / 2.0)); + GEN_DBL_TEST (sinh (M_PI / 3.0)); + GEN_DBL_TEST (sinh (-M_PI / 3.0)); + GEN_DBL_TEST (sinh (M_PI / 4.0)); + GEN_DBL_TEST (sinh (-M_PI / 4.0)); + GEN_DBL_TEST (sinh (M_PI / 6.0)); + GEN_DBL_TEST (sinh (-M_PI / 6.0)); + GEN_DBL_TEST (sinh (M_PI * 2.0 / 3.0)); + GEN_DBL_TEST (sinh (-M_PI * 2.0 / 3.0)); + GEN_DBL_TEST (sinh (M_PI * 5.0 / 6.0)); + GEN_DBL_TEST (sinh (-M_PI * 5.0 / 6.0)); + GEN_DBL_TEST (sinh (6.9e-18)); + GEN_DBL_TEST (sinh (-6.9e-18)); + GEN_DBL_TEST (sinh (7.0e-18)); + GEN_DBL_TEST (sinh (-7.0e-18)); + GEN_DBL_TEST (sinh (7.4e-9)); + GEN_DBL_TEST (sinh (-7.4e-9)); + GEN_DBL_TEST (sinh (7.5e-9)); + GEN_DBL_TEST (sinh (-7.5e-9)); + GEN_DBL_TEST (sinh (0.2)); + GEN_DBL_TEST (sinh (-0.2)); + GEN_DBL_TEST (sinh (0.4)); + GEN_DBL_TEST (sinh (-0.4)); + GEN_DBL_TEST (sinh (0.7)); + GEN_DBL_TEST (sinh (-0.7)); + GEN_DBL_TEST (sinh (0.8)); + GEN_DBL_TEST (sinh (-0.8)); + GEN_DBL_TEST (sinh (3.0)); + GEN_DBL_TEST (sinh (-3.0)); + GEN_DBL_TEST (sinh (4.0)); + GEN_DBL_TEST (sinh (-4.0)); + GEN_DBL_TEST (sinh (6.0)); + GEN_DBL_TEST (sinh (-6.0)); + GEN_DBL_TEST (sinh (7.0)); + GEN_DBL_TEST (sinh (-7.0)); + + /* tanh tests */ + GEN_DBL_TEST (tanh (0.0)); + GEN_DBL_TEST (tanh (-0.0)); + GEN_DBL_TEST (tanh (1.0)); + GEN_DBL_TEST (tanh (-1.0)); + GEN_DBL_TEST (tanh (INFINITY)); + GEN_DBL_TEST (tanh (-INFINITY)); + GEN_DBL_TEST (tanh (NAN)); + GEN_DBL_TEST (tanh (M_PI)); + GEN_DBL_TEST (tanh (-M_PI)); + GEN_DBL_TEST (tanh (2.0 * M_PI)); + GEN_DBL_TEST (tanh (-2.0 * M_PI)); + GEN_DBL_TEST (tanh (M_PI / 2.0)); + GEN_DBL_TEST (tanh (-M_PI / 2.0)); + GEN_DBL_TEST (tanh (M_PI / 3.0)); + GEN_DBL_TEST (tanh (-M_PI / 3.0)); + GEN_DBL_TEST (tanh (M_PI / 4.0)); + GEN_DBL_TEST (tanh (-M_PI / 4.0)); + GEN_DBL_TEST (tanh (M_PI / 6.0)); + GEN_DBL_TEST (tanh (-M_PI / 6.0)); + GEN_DBL_TEST (tanh (M_PI * 2.0 / 3.0)); + GEN_DBL_TEST (tanh (-M_PI * 2.0 / 3.0)); + GEN_DBL_TEST (tanh (M_PI * 5.0 / 6.0)); + GEN_DBL_TEST (tanh (-M_PI * 5.0 / 6.0)); + GEN_DBL_TEST (tanh (6.9e-18)); + GEN_DBL_TEST (tanh (-6.9e-18)); + GEN_DBL_TEST (tanh (7.0e-18)); + GEN_DBL_TEST (tanh (-7.0e-18)); + GEN_DBL_TEST (tanh (7.4e-9)); + GEN_DBL_TEST (tanh (-7.4e-9)); + GEN_DBL_TEST (tanh (7.5e-9)); + GEN_DBL_TEST (tanh (-7.5e-9)); + GEN_DBL_TEST (tanh (0.2)); + GEN_DBL_TEST (tanh (-0.2)); + GEN_DBL_TEST (tanh (0.4)); + GEN_DBL_TEST (tanh (-0.4)); + GEN_DBL_TEST (tanh (0.7)); + GEN_DBL_TEST (tanh (-0.7)); + GEN_DBL_TEST (tanh (0.8)); + GEN_DBL_TEST (tanh (-0.8)); + GEN_DBL_TEST (tanh (3.0)); + GEN_DBL_TEST (tanh (-3.0)); + GEN_DBL_TEST (tanh (4.0)); + GEN_DBL_TEST (tanh (-4.0)); + GEN_DBL_TEST (tanh (6.0)); + GEN_DBL_TEST (tanh (-6.0)); + GEN_DBL_TEST (tanh (7.0)); + GEN_DBL_TEST (tanh (-7.0)); } /* main */