diff options
Diffstat (limited to 'sysdeps/libm-ieee754/s_csinf.c')
-rw-r--r-- | sysdeps/libm-ieee754/s_csinf.c | 104 |
1 files changed, 84 insertions, 20 deletions
diff --git a/sysdeps/libm-ieee754/s_csinf.c b/sysdeps/libm-ieee754/s_csinf.c index f7f10e6b6f..31d2f1fd54 100644 --- a/sysdeps/libm-ieee754/s_csinf.c +++ b/sysdeps/libm-ieee754/s_csinf.c @@ -19,45 +19,109 @@ Boston, MA 02111-1307, USA. */ #include <complex.h> +#include <fenv.h> #include <math.h> +#include "math_private.h" + __complex__ float __csinf (__complex__ float x) { - __complex__ float res; + __complex__ float retval; + int negate = signbit (__real__ x); + int rcls = fpclassify (__real__ x); + int icls = fpclassify (__imag__ x); + + __real__ x = fabsf (__real__ x); - if (!isfinite (__real__ x) || isnan (__imag__ x)) + if (icls >= FP_ZERO) { - if (__real__ x == 0.0 || __imag__ x == 0.0) - { - __real__ res = __nanf (""); - __imag__ res = 0.0; - } - else if (__isinff (__imag__ x)) + /* Imaginary part is finite. */ + if (rcls >= FP_ZERO) { - __real__ res = __nanf (""); - __imag__ res = __imag__ x; + /* Real part is finite. */ + float sinh_val = __ieee754_sinhf (__imag__ x); + float cosh_val = __ieee754_coshf (__imag__ x); + float sinix, cosix; + + __sincosf (__real__ x, &sinix, &cosix); + + __real__ retval = cosh_val * sinix; + __imag__ retval = sinh_val * cosix; + + if (negate) + __real__ retval = -__real__ retval; } else { - __real__ res = __nanf (""); - __imag__ res = __nanf (""); + if (icls == FP_ZERO) + { + /* Imaginary part is 0.0. */ + __real__ retval = __nanf (""); + __imag__ retval = __imag__ x; + +#ifdef FE_INVALID + if (rcls == FP_INFINITE) + feraiseexcept (FE_INVALID); +#endif + } + else + { + __real__ retval = __nanf (""); + __imag__ retval = __nanf (""); + +#ifdef FE_INVALID + feraiseexcept (FE_INVALID); +#endif + } } } - else + else if (icls == FP_INFINITE) { - __complex__ float y; + /* Imaginary part is infinite. */ + if (rcls == FP_ZERO) + { + /* Real part is 0.0. */ + __real__ retval = __copysignf (0.0, negate ? -1.0 : 1.0); + __imag__ retval = __imag__ x; + } + else if (rcls > FP_ZERO) + { + /* Real part is finite. */ + float sinix, cosix; + + __sincosf (__real__ x, &sinix, &cosix); - __real__ y = -__imag__ x; - __imag__ y = __real__ x; + __real__ retval = __copysignf (HUGE_VALF, sinix); + __imag__ retval = __copysignf (HUGE_VALF, cosix); - y = __csinhf (y); + if (negate) + __real__ retval = -__real__ retval; + if (signbit (__imag__ x)) + __imag__ retval = -__imag__ retval; + } + else + { + /* The addition raises the invalid exception. */ + __real__ retval = __nanf (""); + __imag__ retval = HUGE_VALF; - __real__ res = __imag__ y; - __imag__ res = -__real__ y; +#ifdef FE_INVALID + if (rcls == FP_INFINITE) + feraiseexcept (FE_INVALID); +#endif + } + } + else + { + if (rcls == FP_ZERO) + __real__ retval = __copysignf (0.0, negate ? -1.0 : 1.0); + else + __real__ retval = __nanf (""); + __imag__ retval = __nanf (""); } - return res; + return retval; } weak_alias (__csinf, csinf) |