2005-12-13 Ulrich Drepper <drepper@redhat.com>
[platform/upstream/linaro-glibc.git] / math / s_csin.c
1 /* Complex sine function for double.
2    Copyright (C) 1997 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
4    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, write to the Free
18    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19    02111-1307 USA.  */
20
21 #include <complex.h>
22 #include <fenv.h>
23 #include <math.h>
24
25 #include "math_private.h"
26
27
28 __complex__ double
29 __csin (__complex__ double x)
30 {
31   __complex__ double retval;
32   int negate = signbit (__real__ x);
33   int rcls = fpclassify (__real__ x);
34   int icls = fpclassify (__imag__ x);
35
36   __real__ x = fabs (__real__ x);
37
38   if (icls >= FP_ZERO)
39     {
40       /* Imaginary part is finite.  */
41       if (rcls >= FP_ZERO)
42         {
43           /* Real part is finite.  */
44           double sinh_val = __ieee754_sinh (__imag__ x);
45           double cosh_val = __ieee754_cosh (__imag__ x);
46           double sinix, cosix;
47
48           __sincos (__real__ x, &sinix, &cosix);
49
50           __real__ retval = cosh_val * sinix;
51           __imag__ retval = sinh_val * cosix;
52
53           if (negate)
54             __real__ retval = -__real__ retval;
55         }
56       else
57         {
58           if (icls == FP_ZERO)
59             {
60               /* Imaginary part is 0.0.  */
61               __real__ retval = __nan ("");
62               __imag__ retval = __imag__ x;
63
64 #ifdef FE_INVALID
65               if (rcls == FP_INFINITE)
66                 feraiseexcept (FE_INVALID);
67 #endif
68             }
69           else
70             {
71               __real__ retval = __nan ("");
72               __imag__ retval = __nan ("");
73
74 #ifdef FE_INVALID
75               feraiseexcept (FE_INVALID);
76 #endif
77             }
78         }
79     }
80   else if (icls == FP_INFINITE)
81     {
82       /* Imaginary part is infinite.  */
83       if (rcls == FP_ZERO)
84         {
85           /* Real part is 0.0.  */
86           __real__ retval = __copysign (0.0, negate ? -1.0 : 1.0);
87           __imag__ retval = __imag__ x;
88         }
89       else if (rcls > FP_ZERO)
90         {
91           /* Real part is finite.  */
92           double sinix, cosix;
93
94           __sincos (__real__ x, &sinix, &cosix);
95
96           __real__ retval = __copysign (HUGE_VAL, sinix);
97           __imag__ retval = __copysign (HUGE_VAL, cosix);
98
99           if (negate)
100             __real__ retval = -__real__ retval;
101           if (signbit (__imag__ x))
102             __imag__ retval = -__imag__ retval;
103         }
104       else
105         {
106           /* The addition raises the invalid exception.  */
107           __real__ retval = __nan ("");
108           __imag__ retval = HUGE_VAL;
109
110 #ifdef FE_INVALID
111           if (rcls == FP_INFINITE)
112             feraiseexcept (FE_INVALID);
113 #endif
114         }
115     }
116   else
117     {
118       if (rcls == FP_ZERO)
119         __real__ retval = __copysign (0.0, negate ? -1.0 : 1.0);
120       else
121         __real__ retval = __nan ("");
122       __imag__ retval = __nan ("");
123     }
124
125   return retval;
126 }
127 weak_alias (__csin, csin)
128 #ifdef NO_LONG_DOUBLE
129 strong_alias (__csin, __csinl)
130 weak_alias (__csin, csinl)
131 #endif