diff options
Diffstat (limited to 'sysdeps/libm-ieee754')
25 files changed, 530 insertions, 73 deletions
diff --git a/sysdeps/libm-ieee754/s_ccosh.c b/sysdeps/libm-ieee754/s_ccosh.c index b9d7b82f5e..fa958f491b 100644 --- a/sysdeps/libm-ieee754/s_ccosh.c +++ b/sysdeps/libm-ieee754/s_ccosh.c @@ -40,9 +40,12 @@ __ccosh (__complex__ double x) { /* Imaginary part is finite. */ double cosh_val = __ieee754_cosh (__real__ x); + double sinix, cosix; - __real__ retval = cosh_val * __cos (__imag__ x); - __imag__ retval = cosh_val * __sin (__imag__ x); + __sincos (__imag__ x, &sinix, &cosix); + + __real__ retval = cosh_val * cosix; + __imag__ retval = cosh_val * sinix; } else { @@ -62,8 +65,12 @@ __ccosh (__complex__ double x) else if (icls > FP_ZERO) { /* Imaginary part is finite. */ - __real__ retval = __copysign (HUGE_VAL, __cos (__imag__ x)); - __imag__ retval = __copysign (HUGE_VAL, __sin (__imag__ x)); + double sinix, cosix; + + __sincos (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysign (HUGE_VAL, cosix); + __imag__ retval = __copysign (HUGE_VAL, sinix); } else { diff --git a/sysdeps/libm-ieee754/s_ccoshf.c b/sysdeps/libm-ieee754/s_ccoshf.c index 758ec5b579..aeeacbaed0 100644 --- a/sysdeps/libm-ieee754/s_ccoshf.c +++ b/sysdeps/libm-ieee754/s_ccoshf.c @@ -40,9 +40,12 @@ __ccoshf (__complex__ float x) { /* Imaginary part is finite. */ float cosh_val = __ieee754_coshf (__real__ x); + float sinix, cosix; - __real__ retval = cosh_val * __cosf (__imag__ x); - __imag__ retval = cosh_val * __sinf (__imag__ x); + __sincosf (__imag__ x, &sinix, &cosix); + + __real__ retval = cosh_val * cosix; + __imag__ retval = cosh_val * sinix; } else { @@ -62,8 +65,12 @@ __ccoshf (__complex__ float x) else if (icls > FP_ZERO) { /* Imaginary part is finite. */ - __real__ retval = __copysignf (HUGE_VALF, __cosf (__imag__ x)); - __imag__ retval = __copysignf (HUGE_VALF, __sinf (__imag__ x)); + float sinix, cosix; + + __sincosf (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysignf (HUGE_VALF, cosix); + __imag__ retval = __copysignf (HUGE_VALF, sinix); } else { diff --git a/sysdeps/libm-ieee754/s_ccoshl.c b/sysdeps/libm-ieee754/s_ccoshl.c index 5e8c399fb2..9937ba1904 100644 --- a/sysdeps/libm-ieee754/s_ccoshl.c +++ b/sysdeps/libm-ieee754/s_ccoshl.c @@ -40,9 +40,12 @@ __ccoshl (__complex__ long double x) { /* Imaginary part is finite. */ long double cosh_val = __ieee754_coshl (__real__ x); + long double sinix, cosix; - __real__ retval = cosh_val * __cosl (__imag__ x); - __imag__ retval = cosh_val * __sinl (__imag__ x); + __sincosl (__imag__ x, &sinix, &cosix); + + __real__ retval = cosh_val * cosix; + __imag__ retval = cosh_val * sinix; } else { @@ -62,8 +65,12 @@ __ccoshl (__complex__ long double x) else if (icls > FP_ZERO) { /* Imaginary part is finite. */ - __real__ retval = __copysignl (HUGE_VALL, __cosl (__imag__ x)); - __imag__ retval = __copysignl (HUGE_VALL, __sinl (__imag__ x)); + long double sinix, cosix; + + __sincosl (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysignl (HUGE_VALL, cosix); + __imag__ retval = __copysignl (HUGE_VALL, sinix); } else { diff --git a/sysdeps/libm-ieee754/s_cexp.c b/sysdeps/libm-ieee754/s_cexp.c index b99b042d78..5e68f585f7 100644 --- a/sysdeps/libm-ieee754/s_cexp.c +++ b/sysdeps/libm-ieee754/s_cexp.c @@ -1,4 +1,4 @@ -/* Return value of complex exponential function for float complex value. +/* Return value of complex exponential function for double complex value. Copyright (C) 1997 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. @@ -21,17 +21,23 @@ #include <complex.h> #include <math.h> +#include "math_private.h" + __complex__ double __cexp (__complex__ double x) { __complex__ double retval; + int rcls = fpclassify (__real__ x); + int icls = fpclassify (__imag__ x); - if (isfinite (__real__ x)) + if (rcls >= FP_ZERO) { - if (isfinite (__imag__ x)) + /* Real part is finite. */ + if (icls >= FP_ZERO) { - double exp_val = __exp (__real__ x); + /* Imaginary part is finite. */ + double exp_val = __ieee754_exp (__real__ x); if (isfinite (exp_val)) { @@ -52,14 +58,17 @@ __cexp (__complex__ double x) __imag__ retval = __nan (""); } } - else if (__isinf (__real__ x)) + else if (rcls == FP_INFINITE) { - if (isfinite (__imag__ x)) + /* Real part is infinite. */ + if (icls >= FP_ZERO) { + /* Imaginary part is finite. */ double value = signbit (__real__ x) ? 0.0 : HUGE_VAL; - if (__imag__ x == 0.0) + if (icls == FP_ZERO) { + /* Imaginary part is 0.0. */ __real__ retval = value; __imag__ retval = __imag__ x; } diff --git a/sysdeps/libm-ieee754/s_cexpf.c b/sysdeps/libm-ieee754/s_cexpf.c index 0d4372103b..99f33dc873 100644 --- a/sysdeps/libm-ieee754/s_cexpf.c +++ b/sysdeps/libm-ieee754/s_cexpf.c @@ -38,16 +38,19 @@ __cexpf (__complex__ float x) { /* Imaginary part is finite. */ float exp_val = __ieee754_expf (__real__ x); + float sinix, cosix; + + __sincosf (__imag__ x, &sinix, &cosix); if (isfinite (exp_val)) { - __real__ retval = exp_val * __cosf (__imag__ x); - __imag__ retval = exp_val * __sinf (__imag__ x); + __real__ retval = exp_val * cosix; + __imag__ retval = exp_val * sinix; } else { - __real__ retval = __copysignf (exp_val, __cosf (__imag__ x)); - __imag__ retval = __copysignf (exp_val, __sinf (__imag__ x)); + __real__ retval = __copysignf (exp_val, cosix); + __imag__ retval = __copysignf (exp_val, sinix); } } else @@ -74,8 +77,12 @@ __cexpf (__complex__ float x) } else { - __real__ retval = __copysignf (value, __cosf (__imag__ x)); - __imag__ retval = __copysignf (value, __sinf (__imag__ x)); + float sinix, cosix; + + __sincosf (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysignf (value, cosix); + __imag__ retval = __copysignf (value, sinix); } } else if (signbit (__real__ x) == 0) diff --git a/sysdeps/libm-ieee754/s_cexpl.c b/sysdeps/libm-ieee754/s_cexpl.c index ac27e1eeb8..1b97dba74d 100644 --- a/sysdeps/libm-ieee754/s_cexpl.c +++ b/sysdeps/libm-ieee754/s_cexpl.c @@ -38,16 +38,19 @@ __cexpl (__complex__ long double x) { /* Imaginary part is finite. */ long double exp_val = __ieee754_expl (__real__ x); + long double sinix, cosix; + + __sincosl (__imag__ x, &sinix, &cosix); if (isfinite (exp_val)) { - __real__ retval = exp_val * __cosl (__imag__ x); - __imag__ retval = exp_val * __sinl (__imag__ x); + __real__ retval = exp_val * cosix; + __imag__ retval = exp_val * sinix; } else { - __real__ retval = __copysignl (exp_val, __cosl (__imag__ x)); - __imag__ retval = __copysignl (exp_val, __sinl (__imag__ x)); + __real__ retval = __copysignl (exp_val, cosix); + __imag__ retval = __copysignl (exp_val, sinix); } } else @@ -74,8 +77,12 @@ __cexpl (__complex__ long double x) } else { - __real__ retval = __copysignl (value, __cosl (__imag__ x)); - __imag__ retval = __copysignl (value, __sinl (__imag__ x)); + long double sinix, cosix; + + __sincosl (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysignl (value, cosix); + __imag__ retval = __copysignl (value, sinix); } } else if (signbit (__real__ x) == 0) diff --git a/sysdeps/libm-ieee754/s_cosl.c b/sysdeps/libm-ieee754/s_cosl.c index 0e7a06d8ba..9765f7fd4e 100644 --- a/sysdeps/libm-ieee754/s_cosl.c +++ b/sysdeps/libm-ieee754/s_cosl.c @@ -60,14 +60,15 @@ static char rcsid[] = "$NetBSD: $"; #endif { long double y[2],z=0.0; - int32_t n, se; + int32_t n, se, i0, i1; /* High word of x. */ - GET_LDOUBLE_EXP(se,x); + GET_LDOUBLE_WORDS(se,i0,i1,x); /* |x| ~< pi/4 */ se &= 0x7fff; - if(ix <= 0x3ffe) return __kernel_cosl(x,z); + if(se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2)) + return __kernel_cosl(x,z); /* cos(Inf or NaN) is NaN */ else if (se==0x7fff) return x-x; diff --git a/sysdeps/libm-ieee754/s_cproj.c b/sysdeps/libm-ieee754/s_cproj.c new file mode 100644 index 0000000000..8ad27c0e5b --- /dev/null +++ b/sysdeps/libm-ieee754/s_cproj.c @@ -0,0 +1,49 @@ +/* Compute projection of complex double value to Riemann sphere. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <complex.h> +#include <math.h> + + +__complex__ double +__cproj (__complex__ double x) +{ + __complex__ double res; + + if (!finite (__real__ x) || !finite (__imag__ x)) + { + __real__ res = INFINITY; + __imag__ res = __copysign (0.0, __imag__ x); + } + else + { + double den = __real__ x * __real__ x + __imag__ x * __imag__ x + 1.0; + + __real__ res = (2.0 * __real__ x) / den; + __imag__ res = (2.0 * __imag__ x) / den; + } + + return res; +} +weak_alias (__cproj, cproj) +#ifdef NO_LONG_DOUBLE +strong_alias (__cproj, __cprojl) +weak_alias (__cproj, cprojl) +#endif diff --git a/sysdeps/libm-ieee754/s_cprojf.c b/sysdeps/libm-ieee754/s_cprojf.c new file mode 100644 index 0000000000..8ee61c727c --- /dev/null +++ b/sysdeps/libm-ieee754/s_cprojf.c @@ -0,0 +1,45 @@ +/* Compute projection of complex float value to Riemann sphere. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <complex.h> +#include <math.h> + + +__complex__ float +__cprojf (__complex__ float x) +{ + __complex__ float res; + + if (!finite (__real__ x) || !finite (__imag__ x)) + { + __real__ res = INFINITY; + __imag__ res = __copysignf (0.0, __imag__ x); + } + else + { + float den = __real__ x * __real__ x + __imag__ x * __imag__ x + 1.0; + + __real__ res = (2.0 * __real__ x) / den; + __imag__ res = (2.0 * __imag__ x) / den; + } + + return res; +} +weak_alias (__cprojf, cprojf) diff --git a/sysdeps/libm-ieee754/s_cprojl.c b/sysdeps/libm-ieee754/s_cprojl.c new file mode 100644 index 0000000000..34298e1f25 --- /dev/null +++ b/sysdeps/libm-ieee754/s_cprojl.c @@ -0,0 +1,46 @@ +/* Compute projection of complex long double value to Riemann sphere. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <complex.h> +#include <math.h> + + +__complex__ long double +__cprojl (__complex__ long double x) +{ + __complex__ long double res; + + if (!finite (__real__ x) || !finite (__imag__ x)) + { + __real__ res = INFINITY; + __imag__ res = __copysignl (0.0, __imag__ x); + } + else + { + long double den = (__real__ x * __real__ x + __imag__ x * __imag__ x + + 1.0); + + __real__ res = (2.0 * __real__ x) / den; + __imag__ res = (2.0 * __imag__ x) / den; + } + + return res; +} +weak_alias (__cprojl, cprojl) diff --git a/sysdeps/libm-ieee754/s_csinh.c b/sysdeps/libm-ieee754/s_csinh.c index 05cec85e7c..98f06a558f 100644 --- a/sysdeps/libm-ieee754/s_csinh.c +++ b/sysdeps/libm-ieee754/s_csinh.c @@ -40,10 +40,13 @@ __csinh (__complex__ double x) if (icls >= FP_ZERO) { /* Imaginary part is finite. */ - double sinh_val = __ieee754_sinh (__real__ x); + double sinh_val = __ieee754_sinh (__real__ x); + double sinix, cosix; - __real__ retval = sinh_val * __cos (__imag__ x); - __imag__ retval = sinh_val * __sin (__imag__ x); + __sincos (__imag__ x, &sinix, &cosix); + + __real__ retval = sinh_val * cosix; + __imag__ retval = sinh_val * sinix; if (negate) __real__ retval = -__real__ retval; @@ -75,8 +78,12 @@ __csinh (__complex__ double x) else if (icls > FP_ZERO) { /* Imaginary part is finite. */ - __real__ retval = __copysign (HUGE_VAL, __cos (__imag__ x)); - __imag__ retval = __copysign (HUGE_VAL, __sin (__imag__ x)); + double sinix, cosix; + + __sincos (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysign (HUGE_VAL, cosix); + __imag__ retval = __copysign (HUGE_VAL, sinix); if (negate) __real__ retval = -__real__ retval; diff --git a/sysdeps/libm-ieee754/s_csinhf.c b/sysdeps/libm-ieee754/s_csinhf.c index 93f83cf7b6..c644d3a5e8 100644 --- a/sysdeps/libm-ieee754/s_csinhf.c +++ b/sysdeps/libm-ieee754/s_csinhf.c @@ -40,10 +40,13 @@ __csinhf (__complex__ float x) if (icls >= FP_ZERO) { /* Imaginary part is finite. */ - float sinh_val = __ieee754_sinhf (__real__ x); + float sinh_val = __ieee754_sinhf (__real__ x); + float sinix, cosix; - __real__ retval = sinh_val * __cosf (__imag__ x); - __imag__ retval = sinh_val * __sinf (__imag__ x); + __sincosf (__imag__ x, &sinix, &cosix); + + __real__ retval = sinh_val * cosix; + __imag__ retval = sinh_val * sinix; if (negate) __real__ retval = -__real__ retval; @@ -75,8 +78,12 @@ __csinhf (__complex__ float x) else if (icls > FP_ZERO) { /* Imaginary part is finite. */ - __real__ retval = __copysignf (HUGE_VALF, __cosf (__imag__ x)); - __imag__ retval = __copysignf (HUGE_VALF, __sinf (__imag__ x)); + float sinix, cosix; + + __sincosf (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysignf (HUGE_VALF, cosix); + __imag__ retval = __copysignf (HUGE_VALF, sinix); if (negate) __real__ retval = -__real__ retval; diff --git a/sysdeps/libm-ieee754/s_csinhl.c b/sysdeps/libm-ieee754/s_csinhl.c index 8388a40b46..4bb9e63680 100644 --- a/sysdeps/libm-ieee754/s_csinhl.c +++ b/sysdeps/libm-ieee754/s_csinhl.c @@ -41,9 +41,12 @@ __csinhl (__complex__ long double x) { /* Imaginary part is finite. */ long double sinh_val = __ieee754_sinhl (__real__ x); + long double sinix, cosix; - __real__ retval = sinh_val * __cosl (__imag__ x); - __imag__ retval = sinh_val * __sinl (__imag__ x); + __sincosl (__imag__ x, &sinix, &cosix); + + __real__ retval = sinh_val * cosix; + __imag__ retval = sinh_val * sinix; if (negate) __real__ retval = -__real__ retval; @@ -75,8 +78,12 @@ __csinhl (__complex__ long double x) else if (icls > FP_ZERO) { /* Imaginary part is finite. */ - __real__ retval = __copysignl (HUGE_VALL, __cosl (__imag__ x)); - __imag__ retval = __copysignl (HUGE_VALL, __sinl (__imag__ x)); + long double sinix, cosix; + + __sincosl (__imag__ x, &sinix, &cosix); + + __real__ retval = __copysignl (HUGE_VALL, cosix); + __imag__ retval = __copysignl (HUGE_VALL, sinix); if (negate) __real__ retval = -__real__ retval; diff --git a/sysdeps/libm-ieee754/s_ctan.c b/sysdeps/libm-ieee754/s_ctan.c index f448395c7e..069b96c1d6 100644 --- a/sysdeps/libm-ieee754/s_ctan.c +++ b/sysdeps/libm-ieee754/s_ctan.c @@ -48,10 +48,14 @@ __ctan (__complex__ double x) } else { - double den = (__cos (2.0 * __real__ x) - + __ieee754_cosh (2.0 * __imag__ x)); + double sin2rx, cos2rx; + double den; - __real__ res = __sin (2.0 * __real__ x) / den; + __sincos (2.0 * __real__ x, &sin2rx, &cos2rx); + + den = cos2rx + __ieee754_cosh (2.0 * __imag__ x); + + __real__ res = sin2rx / den; __imag__ res = __ieee754_sinh (2.0 * __imag__ x) / den; } diff --git a/sysdeps/libm-ieee754/s_ctanf.c b/sysdeps/libm-ieee754/s_ctanf.c index 99011fa41d..1c6fdca81d 100644 --- a/sysdeps/libm-ieee754/s_ctanf.c +++ b/sysdeps/libm-ieee754/s_ctanf.c @@ -48,10 +48,14 @@ __ctanf (__complex__ float x) } else { - float den = (__cosf (2.0 * __real__ x) - + __ieee754_coshf (2.0 * __imag__ x)); + float sin2rx, cos2rx; + float den; - __real__ res = __sinf (2.0 * __real__ x) / den; + __sincosf (2.0 * __real__ x, &sin2rx, &cos2rx); + + den = cos2rx + __ieee754_coshf (2.0 * __imag__ x); + + __real__ res = sin2rx / den; __imag__ res = __ieee754_sinhf (2.0 * __imag__ x) / den; } diff --git a/sysdeps/libm-ieee754/s_ctanh.c b/sysdeps/libm-ieee754/s_ctanh.c index 7c9b3197ef..a16f9c8d02 100644 --- a/sysdeps/libm-ieee754/s_ctanh.c +++ b/sysdeps/libm-ieee754/s_ctanh.c @@ -48,11 +48,15 @@ __ctanh (__complex__ double x) } else { - double den = (__ieee754_cosh (2.0 * __real__ x) - + __cos (2.0 * __imag__ x)); + double sin2ix, cos2ix; + double den; + + __sincos (2.0 * __imag__ x, &sin2ix, &cos2ix); + + den = (__ieee754_cosh (2.0 * __real__ x) + cos2ix); __real__ res = __ieee754_sinh (2.0 * __real__ x) / den; - __imag__ res = __sin (2.0 * __imag__ x) / den; + __imag__ res = sin2ix / den; } return res; diff --git a/sysdeps/libm-ieee754/s_ctanhf.c b/sysdeps/libm-ieee754/s_ctanhf.c index 1bdbc0fdc5..45548d518c 100644 --- a/sysdeps/libm-ieee754/s_ctanhf.c +++ b/sysdeps/libm-ieee754/s_ctanhf.c @@ -48,11 +48,15 @@ __ctanhf (__complex__ float x) } else { - float den = (__ieee754_coshf (2.0 * __real__ x) - + __cosf (2.0 * __imag__ x)); + float sin2ix, cos2ix; + float den; + + __sincosf (2.0 * __imag__ x, &sin2ix, &cos2ix); + + den = (__ieee754_coshf (2.0 * __real__ x) + cos2ix); __real__ res = __ieee754_sinhf (2.0 * __real__ x) / den; - __imag__ res = __sinf (2.0 * __imag__ x) / den; + __imag__ res = sin2ix / den; } return res; diff --git a/sysdeps/libm-ieee754/s_ctanhl.c b/sysdeps/libm-ieee754/s_ctanhl.c index b34aeb77dd..5c466167a6 100644 --- a/sysdeps/libm-ieee754/s_ctanhl.c +++ b/sysdeps/libm-ieee754/s_ctanhl.c @@ -48,11 +48,15 @@ __ctanhl (__complex__ long double x) } else { - long double den = (__ieee754_coshl (2.0 * __real__ x) - + __cosl (2.0 * __imag__ x)); + long double sin2ix, cos2ix; + long double den; + + __sincosl (2.0 * __imag__ x, &sin2ix, &cos2ix); + + den = (__ieee754_coshl (2.0 * __real__ x) + cos2ix); __real__ res = __ieee754_sinhl (2.0 * __real__ x) / den; - __imag__ res = __sinl (2.0 * __imag__ x) / den; + __imag__ res = sin2ix / den; } return res; diff --git a/sysdeps/libm-ieee754/s_ctanl.c b/sysdeps/libm-ieee754/s_ctanl.c index 82f86fc148..b4a2b4a13c 100644 --- a/sysdeps/libm-ieee754/s_ctanl.c +++ b/sysdeps/libm-ieee754/s_ctanl.c @@ -48,10 +48,14 @@ __ctanl (__complex__ long double x) } else { - long double den = (__cosl (2.0 * __real__ x) - + __ieee754_coshl (2.0 * __imag__ x)); + long double sin2rx, cos2rx; + long double den; - __real__ res = __sinl (2.0 * __real__ x) / den; + __sincosl (2.0 * __real__ x, &sin2rx, &cos2rx); + + den = cos2rx + __ieee754_coshl (2.0 * __imag__ x); + + __real__ res = sin2rx / den; __imag__ res = __ieee754_sinhl (2.0 * __imag__ x) / den; } diff --git a/sysdeps/libm-ieee754/s_roundtol.c b/sysdeps/libm-ieee754/s_roundtol.c index 6649369b06..bc0ceae0f8 100644 --- a/sysdeps/libm-ieee754/s_roundtol.c +++ b/sysdeps/libm-ieee754/s_roundtol.c @@ -63,7 +63,7 @@ __roundtol (long double x) } else { - i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); + u_int32_t i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); if ((i1 & i) != 0) { /* x is not integral. */ @@ -93,7 +93,7 @@ __roundtol (long double x) { result = (long int) ((i0 & 0xfffff) | 0x100000) << (j0 - 31); if (sizeof (long int) > 4 && j0 > 31) - result |= j >> (63 - j0); + result |= i1 >> (63 - j0); } } diff --git a/sysdeps/libm-ieee754/s_roundtoll.c b/sysdeps/libm-ieee754/s_roundtoll.c index 8d99130697..49167236a6 100644 --- a/sysdeps/libm-ieee754/s_roundtoll.c +++ b/sysdeps/libm-ieee754/s_roundtoll.c @@ -63,7 +63,7 @@ __roundtoll (long double x) } else { - i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); + u_int32_t i = ((u_int32_t) (0xffffffff)) >> (j0 - 20); if ((i1 & i) != 0) { /* x is not integral. */ @@ -95,7 +95,7 @@ __roundtoll (long double x) { result = (long long int) ((i0 & 0xfffff) | 0x100000) << (j0 - 31); if (sizeof (long long int) > 4 && j0 > 31) - result |= j >> (63 - j0); + result |= i1 >> (63 - j0); } } diff --git a/sysdeps/libm-ieee754/s_sincos.c b/sysdeps/libm-ieee754/s_sincos.c new file mode 100644 index 0000000000..5bc564ba5b --- /dev/null +++ b/sysdeps/libm-ieee754/s_sincos.c @@ -0,0 +1,78 @@ +/* Compute sine and cosine of argument. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <math.h> + +#include "math_private.h" + + +void +__sincos (double x, double *sinx, double *cosx) +{ + int32_t ix; + + /* High word of x. */ + GET_HIGH_WORD (ix, x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3fe921fb) + { + *sinx = __kernel_sin (x, 0.0, 0); + *cosx = __kernel_cos (x, 0.0); + } + else if (ix>=0x7ff00000) + { + /* sin(Inf or NaN) is NaN */ + *sinx = *cosx = x - x; + } + else + { + /* Argument reduction needed. */ + double y[2]; + int n; + + n = __ieee754_rem_pio2 (x, y); + switch (n & 3) + { + case 0: + *sinx = __kernel_sin (y[0], y[1], 1); + *cosx = __kernel_cos (y[0], y[1]); + break; + case 1: + *sinx = __kernel_cos (y[0], y[1]); + *cosx = -__kernel_sin (y[0], y[1], 1); + break; + case 2: + *sinx = -__kernel_sin (y[0], y[1], 1); + *cosx = -__kernel_cos (y[0], y[1]); + break; + default: + *sinx = -__kernel_cos (y[0], y[1]); + *cosx = __kernel_sin (y[0], y[1], 1); + break; + } + } +} +weak_alias (__sincos, sincos) +#ifdef NO_LONG_DOUBLE +strong_alias (__sincos, __sincosl) +weak_alias (__sincos, sincosl) +#endif diff --git a/sysdeps/libm-ieee754/s_sincosf.c b/sysdeps/libm-ieee754/s_sincosf.c new file mode 100644 index 0000000000..0fd7b0ca8b --- /dev/null +++ b/sysdeps/libm-ieee754/s_sincosf.c @@ -0,0 +1,74 @@ +/* Compute sine and cosine of argument. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <math.h> + +#include "math_private.h" + + +void +__sincosf (float x, float *sinx, float *cosx) +{ + int32_t ix; + + /* High word of x. */ + GET_FLOAT_WORD (ix, x); + + /* |x| ~< pi/4 */ + ix &= 0x7fffffff; + if (ix <= 0x3f490fd8) + { + *sinx = __kernel_sinf (x, 0.0, 0); + *cosx = __kernel_cosf (x, 0.0); + } + else if (ix>=0x7ff00000) + { + /* sin(Inf or NaN) is NaN */ + *sinx = *cosx = x - x; + } + else + { + /* Argument reduction needed. */ + float y[2]; + int n; + + n = __ieee754_rem_pio2f (x, y); + switch (n & 3) + { + case 0: + *sinx = __kernel_sinf (y[0], y[1], 1); + *cosx = __kernel_cosf (y[0], y[1]); + break; + case 1: + *sinx = __kernel_cosf (y[0], y[1]); + *cosx = -__kernel_sinf (y[0], y[1], 1); + break; + case 2: + *sinx = -__kernel_sinf (y[0], y[1], 1); + *cosx = -__kernel_cosf (y[0], y[1]); + break; + default: + *sinx = -__kernel_cosf (y[0], y[1]); + *cosx = __kernel_sinf (y[0], y[1], 1); + break; + } + } +} +weak_alias (__sincosf, sincosf) diff --git a/sysdeps/libm-ieee754/s_sincosl.c b/sysdeps/libm-ieee754/s_sincosl.c new file mode 100644 index 0000000000..7cadf88a40 --- /dev/null +++ b/sysdeps/libm-ieee754/s_sincosl.c @@ -0,0 +1,74 @@ +/* Compute sine and cosine of argument. + Copyright (C) 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include <math.h> + +#include "math_private.h" + + +void +__sincosl (long double x, long double *sinx, long double *cosx) +{ + int32_t se, i0, i1; + + /* High word of x. */ + GET_LDOUBLE_WORDS (se, i0, i1, x); + + /* |x| ~< pi/4 */ + se &= 0x7fff; + if (se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2)) + { + *sinx = __kernel_sinl (x, 0.0, 0); + *cosx = __kernel_cosl (x, 0.0); + } + else if (ix == 0x7fff) + { + /* sin(Inf or NaN) is NaN */ + *sinx = *cosx = x - x; + } + else + { + /* Argument reduction needed. */ + long double y[2]; + int n; + + n = __ieee754_rem_pio2l (x, y); + switch (n & 3) + { + case 0: + *sinx = __kernel_sinl (y[0], y[1], 1); + *cosx = __kernel_cosl (y[0], y[1]); + break; + case 1: + *sinx = __kernel_cosl (y[0], y[1]); + *cosx = -__kernel_sinl (y[0], y[1], 1); + break; + case 2: + *sinx = -__kernel_sinl (y[0], y[1], 1); + *cosx = -__kernel_cosl (y[0], y[1]); + break; + default: + *sinx = -__kernel_cosl (y[0], y[1]); + *cosx = __kernel_sinl (y[0], y[1], 1); + break; + } + } +} +weak_alias (__sincosl, sincosl) diff --git a/sysdeps/libm-ieee754/s_sinl.c b/sysdeps/libm-ieee754/s_sinl.c index ade86dfa66..4fd48805b4 100644 --- a/sysdeps/libm-ieee754/s_sinl.c +++ b/sysdeps/libm-ieee754/s_sinl.c @@ -60,14 +60,15 @@ static char rcsid[] = "$NetBSD: $"; #endif { long double y[2],z=0.0; - int32_t n, se; + int32_t n, se, i0, i1; /* High word of x. */ - GET_LDOUBLE_EXP(se,x); + GET_LDOUBLE_WORDS(se,i0,i1,x); /* |x| ~< pi/4 */ se &= 0x7fff; - if(se <= 0x3ffe) return __kernel_sinl(x,z,0); + if(se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2)) + return __kernel_sinl(x,z,0); /* sin(Inf or NaN) is NaN */ else if (se==0x7fff) return x-x; |