1*627f7eb2Smrg /* Complex sine function for float types.
2*627f7eb2Smrg Copyright (C) 1997-2018 Free Software Foundation, Inc.
3*627f7eb2Smrg This file is part of the GNU C Library.
4*627f7eb2Smrg Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
5*627f7eb2Smrg
6*627f7eb2Smrg The GNU C Library is free software; you can redistribute it and/or
7*627f7eb2Smrg modify it under the terms of the GNU Lesser General Public
8*627f7eb2Smrg License as published by the Free Software Foundation; either
9*627f7eb2Smrg version 2.1 of the License, or (at your option) any later version.
10*627f7eb2Smrg
11*627f7eb2Smrg The GNU C Library is distributed in the hope that it will be useful,
12*627f7eb2Smrg but WITHOUT ANY WARRANTY; without even the implied warranty of
13*627f7eb2Smrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*627f7eb2Smrg Lesser General Public License for more details.
15*627f7eb2Smrg
16*627f7eb2Smrg You should have received a copy of the GNU Lesser General Public
17*627f7eb2Smrg License along with the GNU C Library; if not, see
18*627f7eb2Smrg <http://www.gnu.org/licenses/>. */
19*627f7eb2Smrg
20*627f7eb2Smrg #include "quadmath-imp.h"
21*627f7eb2Smrg
22*627f7eb2Smrg __complex128
csinq(__complex128 x)23*627f7eb2Smrg csinq (__complex128 x)
24*627f7eb2Smrg {
25*627f7eb2Smrg __complex128 retval;
26*627f7eb2Smrg int negate = signbitq (__real__ x);
27*627f7eb2Smrg int rcls = fpclassifyq (__real__ x);
28*627f7eb2Smrg int icls = fpclassifyq (__imag__ x);
29*627f7eb2Smrg
30*627f7eb2Smrg __real__ x = fabsq (__real__ x);
31*627f7eb2Smrg
32*627f7eb2Smrg if (__glibc_likely (icls >= QUADFP_ZERO))
33*627f7eb2Smrg {
34*627f7eb2Smrg /* Imaginary part is finite. */
35*627f7eb2Smrg if (__glibc_likely (rcls >= QUADFP_ZERO))
36*627f7eb2Smrg {
37*627f7eb2Smrg /* Real part is finite. */
38*627f7eb2Smrg const int t = (int) ((FLT128_MAX_EXP - 1) * M_LN2q);
39*627f7eb2Smrg __float128 sinix, cosix;
40*627f7eb2Smrg
41*627f7eb2Smrg if (__glibc_likely (__real__ x > FLT128_MIN))
42*627f7eb2Smrg {
43*627f7eb2Smrg sincosq (__real__ x, &sinix, &cosix);
44*627f7eb2Smrg }
45*627f7eb2Smrg else
46*627f7eb2Smrg {
47*627f7eb2Smrg sinix = __real__ x;
48*627f7eb2Smrg cosix = 1;
49*627f7eb2Smrg }
50*627f7eb2Smrg
51*627f7eb2Smrg if (negate)
52*627f7eb2Smrg sinix = -sinix;
53*627f7eb2Smrg
54*627f7eb2Smrg if (fabsq (__imag__ x) > t)
55*627f7eb2Smrg {
56*627f7eb2Smrg __float128 exp_t = expq (t);
57*627f7eb2Smrg __float128 ix = fabsq (__imag__ x);
58*627f7eb2Smrg if (signbitq (__imag__ x))
59*627f7eb2Smrg cosix = -cosix;
60*627f7eb2Smrg ix -= t;
61*627f7eb2Smrg sinix *= exp_t / 2;
62*627f7eb2Smrg cosix *= exp_t / 2;
63*627f7eb2Smrg if (ix > t)
64*627f7eb2Smrg {
65*627f7eb2Smrg ix -= t;
66*627f7eb2Smrg sinix *= exp_t;
67*627f7eb2Smrg cosix *= exp_t;
68*627f7eb2Smrg }
69*627f7eb2Smrg if (ix > t)
70*627f7eb2Smrg {
71*627f7eb2Smrg /* Overflow (original imaginary part of x > 3t). */
72*627f7eb2Smrg __real__ retval = FLT128_MAX * sinix;
73*627f7eb2Smrg __imag__ retval = FLT128_MAX * cosix;
74*627f7eb2Smrg }
75*627f7eb2Smrg else
76*627f7eb2Smrg {
77*627f7eb2Smrg __float128 exp_val = expq (ix);
78*627f7eb2Smrg __real__ retval = exp_val * sinix;
79*627f7eb2Smrg __imag__ retval = exp_val * cosix;
80*627f7eb2Smrg }
81*627f7eb2Smrg }
82*627f7eb2Smrg else
83*627f7eb2Smrg {
84*627f7eb2Smrg __real__ retval = coshq (__imag__ x) * sinix;
85*627f7eb2Smrg __imag__ retval = sinhq (__imag__ x) * cosix;
86*627f7eb2Smrg }
87*627f7eb2Smrg
88*627f7eb2Smrg math_check_force_underflow_complex (retval);
89*627f7eb2Smrg }
90*627f7eb2Smrg else
91*627f7eb2Smrg {
92*627f7eb2Smrg if (icls == QUADFP_ZERO)
93*627f7eb2Smrg {
94*627f7eb2Smrg /* Imaginary part is 0.0. */
95*627f7eb2Smrg __real__ retval = __real__ x - __real__ x;
96*627f7eb2Smrg __imag__ retval = __imag__ x;
97*627f7eb2Smrg }
98*627f7eb2Smrg else
99*627f7eb2Smrg {
100*627f7eb2Smrg __real__ retval = nanq ("");
101*627f7eb2Smrg __imag__ retval = nanq ("");
102*627f7eb2Smrg
103*627f7eb2Smrg feraiseexcept (FE_INVALID);
104*627f7eb2Smrg }
105*627f7eb2Smrg }
106*627f7eb2Smrg }
107*627f7eb2Smrg else if (icls == QUADFP_INFINITE)
108*627f7eb2Smrg {
109*627f7eb2Smrg /* Imaginary part is infinite. */
110*627f7eb2Smrg if (rcls == QUADFP_ZERO)
111*627f7eb2Smrg {
112*627f7eb2Smrg /* Real part is 0.0. */
113*627f7eb2Smrg __real__ retval = copysignq (0, negate ? -1 : 1);
114*627f7eb2Smrg __imag__ retval = __imag__ x;
115*627f7eb2Smrg }
116*627f7eb2Smrg else if (rcls > QUADFP_ZERO)
117*627f7eb2Smrg {
118*627f7eb2Smrg /* Real part is finite. */
119*627f7eb2Smrg __float128 sinix, cosix;
120*627f7eb2Smrg
121*627f7eb2Smrg if (__glibc_likely (__real__ x > FLT128_MIN))
122*627f7eb2Smrg {
123*627f7eb2Smrg sincosq (__real__ x, &sinix, &cosix);
124*627f7eb2Smrg }
125*627f7eb2Smrg else
126*627f7eb2Smrg {
127*627f7eb2Smrg sinix = __real__ x;
128*627f7eb2Smrg cosix = 1;
129*627f7eb2Smrg }
130*627f7eb2Smrg
131*627f7eb2Smrg __real__ retval = copysignq (HUGE_VALQ, sinix);
132*627f7eb2Smrg __imag__ retval = copysignq (HUGE_VALQ, cosix);
133*627f7eb2Smrg
134*627f7eb2Smrg if (negate)
135*627f7eb2Smrg __real__ retval = -__real__ retval;
136*627f7eb2Smrg if (signbitq (__imag__ x))
137*627f7eb2Smrg __imag__ retval = -__imag__ retval;
138*627f7eb2Smrg }
139*627f7eb2Smrg else
140*627f7eb2Smrg {
141*627f7eb2Smrg __real__ retval = __real__ x - __real__ x;
142*627f7eb2Smrg __imag__ retval = HUGE_VALQ;
143*627f7eb2Smrg }
144*627f7eb2Smrg }
145*627f7eb2Smrg else
146*627f7eb2Smrg {
147*627f7eb2Smrg if (rcls == QUADFP_ZERO)
148*627f7eb2Smrg __real__ retval = copysignq (0, negate ? -1 : 1);
149*627f7eb2Smrg else
150*627f7eb2Smrg __real__ retval = nanq ("");
151*627f7eb2Smrg __imag__ retval = nanq ("");
152*627f7eb2Smrg }
153*627f7eb2Smrg
154*627f7eb2Smrg return retval;
155*627f7eb2Smrg }
156