(root)/
gcc-13.2.0/
libquadmath/
math/
csinhq.c
       1  /* Complex sine hyperbole function for float types.
       2     Copyright (C) 1997-2018 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, see
      18     <http://www.gnu.org/licenses/>.  */
      19  
      20  #include "quadmath-imp.h"
      21  
      22  __complex128
      23  csinhq (__complex128 x)
      24  {
      25    __complex128 retval;
      26    int negate = signbitq (__real__ x);
      27    int rcls = fpclassifyq (__real__ x);
      28    int icls = fpclassifyq (__imag__ x);
      29  
      30    __real__ x = fabsq (__real__ x);
      31  
      32    if (__glibc_likely (rcls >= QUADFP_ZERO))
      33      {
      34        /* Real part is finite.  */
      35        if (__glibc_likely (icls >= QUADFP_ZERO))
      36  	{
      37  	  /* Imaginary part is finite.  */
      38  	  const int t = (int) ((FLT128_MAX_EXP - 1) * M_LN2q);
      39  	  __float128 sinix, cosix;
      40  
      41  	  if (__glibc_likely (fabsq (__imag__ x) > FLT128_MIN))
      42  	    {
      43  	      sincosq (__imag__ x, &sinix, &cosix);
      44  	    }
      45  	  else
      46  	    {
      47  	      sinix = __imag__ x;
      48  	      cosix = 1;
      49  	    }
      50  
      51  	  if (negate)
      52  	    cosix = -cosix;
      53  
      54  	  if (fabsq (__real__ x) > t)
      55  	    {
      56  	      __float128 exp_t = expq (t);
      57  	      __float128 rx = fabsq (__real__ x);
      58  	      if (signbitq (__real__ x))
      59  		cosix = -cosix;
      60  	      rx -= t;
      61  	      sinix *= exp_t / 2;
      62  	      cosix *= exp_t / 2;
      63  	      if (rx > t)
      64  		{
      65  		  rx -= t;
      66  		  sinix *= exp_t;
      67  		  cosix *= exp_t;
      68  		}
      69  	      if (rx > t)
      70  		{
      71  		  /* Overflow (original real part of x > 3t).  */
      72  		  __real__ retval = FLT128_MAX * cosix;
      73  		  __imag__ retval = FLT128_MAX * sinix;
      74  		}
      75  	      else
      76  		{
      77  		  __float128 exp_val = expq (rx);
      78  		  __real__ retval = exp_val * cosix;
      79  		  __imag__ retval = exp_val * sinix;
      80  		}
      81  	    }
      82  	  else
      83  	    {
      84  	      __real__ retval = sinhq (__real__ x) * cosix;
      85  	      __imag__ retval = coshq (__real__ x) * sinix;
      86  	    }
      87  
      88  	  math_check_force_underflow_complex (retval);
      89  	}
      90        else
      91  	{
      92  	  if (rcls == QUADFP_ZERO)
      93  	    {
      94  	      /* Real part is 0.0.  */
      95  	      __real__ retval = copysignq (0, negate ? -1 : 1);
      96  	      __imag__ retval = __imag__ x - __imag__ x;
      97  	    }
      98  	  else
      99  	    {
     100  	      __real__ retval = nanq ("");
     101  	      __imag__ retval = nanq ("");
     102  
     103  	      feraiseexcept (FE_INVALID);
     104  	    }
     105  	}
     106      }
     107    else if (rcls == QUADFP_INFINITE)
     108      {
     109        /* Real part is infinite.  */
     110        if (__glibc_likely (icls > QUADFP_ZERO))
     111  	{
     112  	  /* Imaginary part is finite.  */
     113  	  __float128 sinix, cosix;
     114  
     115  	  if (__glibc_likely (fabsq (__imag__ x) > FLT128_MIN))
     116  	    {
     117  	      sincosq (__imag__ x, &sinix, &cosix);
     118  	    }
     119  	  else
     120  	    {
     121  	      sinix = __imag__ x;
     122  	      cosix = 1;
     123  	    }
     124  
     125  	  __real__ retval = copysignq (HUGE_VALQ, cosix);
     126  	  __imag__ retval = copysignq (HUGE_VALQ, sinix);
     127  
     128  	  if (negate)
     129  	    __real__ retval = -__real__ retval;
     130  	}
     131        else if (icls == QUADFP_ZERO)
     132  	{
     133  	  /* Imaginary part is 0.0.  */
     134  	  __real__ retval = negate ? -HUGE_VALQ : HUGE_VALQ;
     135  	  __imag__ retval = __imag__ x;
     136  	}
     137        else
     138  	{
     139  	  __real__ retval = HUGE_VALQ;
     140  	  __imag__ retval = __imag__ x - __imag__ x;
     141  	}
     142      }
     143    else
     144      {
     145        __real__ retval = nanq ("");
     146        __imag__ retval = __imag__ x == 0 ? __imag__ x : nanq ("");
     147      }
     148  
     149    return retval;
     150  }