summaryrefslogtreecommitdiff
path: root/sysdeps/libm-ieee754
diff options
context:
space:
mode:
Diffstat (limited to 'sysdeps/libm-ieee754')
-rw-r--r--sysdeps/libm-ieee754/s_ccosh.c15
-rw-r--r--sysdeps/libm-ieee754/s_ccoshf.c15
-rw-r--r--sysdeps/libm-ieee754/s_ccoshl.c15
-rw-r--r--sysdeps/libm-ieee754/s_cexp.c23
-rw-r--r--sysdeps/libm-ieee754/s_cexpf.c19
-rw-r--r--sysdeps/libm-ieee754/s_cexpl.c19
-rw-r--r--sysdeps/libm-ieee754/s_cosl.c7
-rw-r--r--sysdeps/libm-ieee754/s_cproj.c49
-rw-r--r--sysdeps/libm-ieee754/s_cprojf.c45
-rw-r--r--sysdeps/libm-ieee754/s_cprojl.c46
-rw-r--r--sysdeps/libm-ieee754/s_csinh.c17
-rw-r--r--sysdeps/libm-ieee754/s_csinhf.c17
-rw-r--r--sysdeps/libm-ieee754/s_csinhl.c15
-rw-r--r--sysdeps/libm-ieee754/s_ctan.c10
-rw-r--r--sysdeps/libm-ieee754/s_ctanf.c10
-rw-r--r--sysdeps/libm-ieee754/s_ctanh.c10
-rw-r--r--sysdeps/libm-ieee754/s_ctanhf.c10
-rw-r--r--sysdeps/libm-ieee754/s_ctanhl.c10
-rw-r--r--sysdeps/libm-ieee754/s_ctanl.c10
-rw-r--r--sysdeps/libm-ieee754/s_roundtol.c4
-rw-r--r--sysdeps/libm-ieee754/s_roundtoll.c4
-rw-r--r--sysdeps/libm-ieee754/s_sincos.c78
-rw-r--r--sysdeps/libm-ieee754/s_sincosf.c74
-rw-r--r--sysdeps/libm-ieee754/s_sincosl.c74
-rw-r--r--sysdeps/libm-ieee754/s_sinl.c7
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;