xref: /netbsd-src/external/gpl3/gcc.old/dist/libquadmath/math/csinq.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
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