diff --git a/math/s_ctanh.c b/math/s_ctanh.c index fe38dae..31d7cfb 100644 --- a/math/s_ctanh.c +++ b/math/s_ctanh.c @@ -2,6 +2,7 @@ Copyright (C) 1997, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. + Improvements by Judd Storrs and Jaroslav Hajek, 2010. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -54,12 +55,20 @@ __ctanh (__complex__ double x) } else { - double sin2ix, cos2ix; + double sinix, cosix, sinhx, coshx; double den; - __sincos (2.0 * __imag__ x, &sin2ix, &cos2ix); + /* + * sinh(a)*cosh(a) + i*sin(b)*cos(b) + * ctanh(a+bi) = --------------------------------- + * cos(b)^2 + sinh(a)^2 + */ - den = (__ieee754_cosh (2.0 * __real__ x) + cos2ix); + __sincos (__imag__ x, &sinix, &cosix); + sinhx = __ieee754_sinh (__real__ x); + coshx = __ieee754_cosh (__real__ x); + + den = sinhx*sinhx + cosix*cosix; if (den == 0.0) { @@ -70,8 +79,8 @@ __ctanh (__complex__ double x) } else { - __real__ res = __ieee754_sinh (2.0 * __real__ x) / den; - __imag__ res = sin2ix / den; + __real__ res = isfinite (den) ? sinhx * coshx / den : __copysign (1.0, __real__ x); + __imag__ res = sinix * cosix / den; } } diff --git a/math/s_ctanhf.c b/math/s_ctanhf.c index c331dba..fd3fbca 100644 --- a/math/s_ctanhf.c +++ b/math/s_ctanhf.c @@ -2,6 +2,7 @@ Copyright (C) 1997, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. + Improvements by Judd Storrs and Jaroslav Hajek, 2010. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -54,12 +55,20 @@ __ctanhf (__complex__ float x) } else { - float sin2ix, cos2ix; + float sinix, cosix, sinhx, coshx; float den; - __sincosf (2.0 * __imag__ x, &sin2ix, &cos2ix); + /* + * sinh(a)*cosh(a) + i*sin(b)*cos(b) + * ctanh(a+bi) = --------------------------------- + * cos(b)^2 + sinh(a)^2 + */ - den = (__ieee754_coshf (2.0 * __real__ x) + cos2ix); + __sincosf (__imag__ x, &sinix, &cosix); + sinhx = __ieee754_sinhf (__real__ x); + coshx = __ieee754_coshf (__real__ x); + + den = sinhx*sinhx + cosix*cosix; if (den == 0.0f) { @@ -70,8 +79,8 @@ __ctanhf (__complex__ float x) } else { - __real__ res = __ieee754_sinhf (2.0 * __real__ x) / den; - __imag__ res = sin2ix / den; + __real__ res = isfinite (den) ? sinhx * coshx / den : __copysignf (1.0, __real__ x); + __imag__ res = sinix * cosix / den; } } diff --git a/math/s_ctanhl.c b/math/s_ctanhl.c index 77ca8f8..28bf458 100644 --- a/math/s_ctanhl.c +++ b/math/s_ctanhl.c @@ -2,6 +2,7 @@ Copyright (C) 1997, 2005 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 1997. + Improvements by Judd Storrs and Jaroslav Hajek, 2010. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -54,12 +55,20 @@ __ctanhl (__complex__ long double x) } else { - long double sin2ix, cos2ix; + long double sinix, cosix, sinhx, coshx; long double den; - __sincosl (2.0 * __imag__ x, &sin2ix, &cos2ix); + /* + * sinh(a)*cosh(a) + i*sin(b)*cos(b) + * ctanh(a+bi) = --------------------------------- + * cos(b)^2 + sinh(a)^2 + */ - den = (__ieee754_coshl (2.0 * __real__ x) + cos2ix); + __sincosl (__imag__ x, &sinix, &cosix); + sinhx = __ieee754_sinhl (__real__ x); + coshx = __ieee754_coshl (__real__ x); + + den = sinhx*sinhx + cosix*cosix; if (den == 0.0L) { @@ -70,8 +79,8 @@ __ctanhl (__complex__ long double x) } else { - __real__ res = __ieee754_sinhl (2.0 * __real__ x) / den; - __imag__ res = sin2ix / den; + __real__ res = isfinite (den) ? sinhx * coshx / den : __copysignl (1.0L, __real__ x); + __imag__ res = sinix * cosix / den; } }