Home | History | Annotate | Line # | Download | only in math
      1  1.1  mrg /* Return arc tangent of complex float type.
      2  1.1  mrg    Copyright (C) 1997-2018 Free Software Foundation, Inc.
      3  1.1  mrg    This file is part of the GNU C Library.
      4  1.1  mrg    Contributed by Ulrich Drepper <drepper (at) cygnus.com>, 1997.
      5  1.1  mrg 
      6  1.1  mrg    The GNU C Library is free software; you can redistribute it and/or
      7  1.1  mrg    modify it under the terms of the GNU Lesser General Public
      8  1.1  mrg    License as published by the Free Software Foundation; either
      9  1.1  mrg    version 2.1 of the License, or (at your option) any later version.
     10  1.1  mrg 
     11  1.1  mrg    The GNU C Library is distributed in the hope that it will be useful,
     12  1.1  mrg    but WITHOUT ANY WARRANTY; without even the implied warranty of
     13  1.1  mrg    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
     14  1.1  mrg    Lesser General Public License for more details.
     15  1.1  mrg 
     16  1.1  mrg    You should have received a copy of the GNU Lesser General Public
     17  1.1  mrg    License along with the GNU C Library; if not, see
     18  1.1  mrg    <http://www.gnu.org/licenses/>.  */
     19  1.1  mrg 
     20  1.1  mrg #include "quadmath-imp.h"
     21  1.1  mrg 
     22  1.1  mrg __complex128
     23  1.1  mrg catanq (__complex128 x)
     24  1.1  mrg {
     25  1.1  mrg   __complex128 res;
     26  1.1  mrg   int rcls = fpclassifyq (__real__ x);
     27  1.1  mrg   int icls = fpclassifyq (__imag__ x);
     28  1.1  mrg 
     29  1.1  mrg   if (__glibc_unlikely (rcls <= QUADFP_INFINITE || icls <= QUADFP_INFINITE))
     30  1.1  mrg     {
     31  1.1  mrg       if (rcls == QUADFP_INFINITE)
     32  1.1  mrg 	{
     33  1.1  mrg 	  __real__ res = copysignq (M_PI_2q, __real__ x);
     34  1.1  mrg 	  __imag__ res = copysignq (0, __imag__ x);
     35  1.1  mrg 	}
     36  1.1  mrg       else if (icls == QUADFP_INFINITE)
     37  1.1  mrg 	{
     38  1.1  mrg 	  if (rcls >= QUADFP_ZERO)
     39  1.1  mrg 	    __real__ res = copysignq (M_PI_2q, __real__ x);
     40  1.1  mrg 	  else
     41  1.1  mrg 	    __real__ res = nanq ("");
     42  1.1  mrg 	  __imag__ res = copysignq (0, __imag__ x);
     43  1.1  mrg 	}
     44  1.1  mrg       else if (icls == QUADFP_ZERO || icls == QUADFP_INFINITE)
     45  1.1  mrg 	{
     46  1.1  mrg 	  __real__ res = nanq ("");
     47  1.1  mrg 	  __imag__ res = copysignq (0, __imag__ x);
     48  1.1  mrg 	}
     49  1.1  mrg       else
     50  1.1  mrg 	{
     51  1.1  mrg 	  __real__ res = nanq ("");
     52  1.1  mrg 	  __imag__ res = nanq ("");
     53  1.1  mrg 	}
     54  1.1  mrg     }
     55  1.1  mrg   else if (__glibc_unlikely (rcls == QUADFP_ZERO && icls == QUADFP_ZERO))
     56  1.1  mrg     {
     57  1.1  mrg       res = x;
     58  1.1  mrg     }
     59  1.1  mrg   else
     60  1.1  mrg     {
     61  1.1  mrg       if (fabsq (__real__ x) >= 16 / FLT128_EPSILON
     62  1.1  mrg 	  || fabsq (__imag__ x) >= 16 / FLT128_EPSILON)
     63  1.1  mrg 	{
     64  1.1  mrg 	  __real__ res = copysignq (M_PI_2q, __real__ x);
     65  1.1  mrg 	  if (fabsq (__real__ x) <= 1)
     66  1.1  mrg 	    __imag__ res = 1 / __imag__ x;
     67  1.1  mrg 	  else if (fabsq (__imag__ x) <= 1)
     68  1.1  mrg 	    __imag__ res = __imag__ x / __real__ x / __real__ x;
     69  1.1  mrg 	  else
     70  1.1  mrg 	    {
     71  1.1  mrg 	      __float128 h = hypotq (__real__ x / 2, __imag__ x / 2);
     72  1.1  mrg 	      __imag__ res = __imag__ x / h / h / 4;
     73  1.1  mrg 	    }
     74  1.1  mrg 	}
     75  1.1  mrg       else
     76  1.1  mrg 	{
     77  1.1  mrg 	  __float128 den, absx, absy;
     78  1.1  mrg 
     79  1.1  mrg 	  absx = fabsq (__real__ x);
     80  1.1  mrg 	  absy = fabsq (__imag__ x);
     81  1.1  mrg 	  if (absx < absy)
     82  1.1  mrg 	    {
     83  1.1  mrg 	      __float128 t = absx;
     84  1.1  mrg 	      absx = absy;
     85  1.1  mrg 	      absy = t;
     86  1.1  mrg 	    }
     87  1.1  mrg 
     88  1.1  mrg 	  if (absy < FLT128_EPSILON / 2)
     89  1.1  mrg 	    {
     90  1.1  mrg 	      den = (1 - absx) * (1 + absx);
     91  1.1  mrg 	      if (den == 0)
     92  1.1  mrg 		den = 0;
     93  1.1  mrg 	    }
     94  1.1  mrg 	  else if (absx >= 1)
     95  1.1  mrg 	    den = (1 - absx) * (1 + absx) - absy * absy;
     96  1.1  mrg 	  else if (absx >= 0.75Q || absy >= 0.5Q)
     97  1.1  mrg 	    den = -__quadmath_x2y2m1q (absx, absy);
     98  1.1  mrg 	  else
     99  1.1  mrg 	    den = (1 - absx) * (1 + absx) - absy * absy;
    100  1.1  mrg 
    101  1.1  mrg 	  __real__ res = 0.5Q * atan2q (2 * __real__ x, den);
    102  1.1  mrg 
    103  1.1  mrg 	  if (fabsq (__imag__ x) == 1
    104  1.1  mrg 	      && fabsq (__real__ x) < FLT128_EPSILON * FLT128_EPSILON)
    105  1.1  mrg 	    __imag__ res = (copysignq (0.5Q, __imag__ x)
    106  1.1  mrg 			    * ((__float128) M_LN2q
    107  1.1  mrg 			       - logq (fabsq (__real__ x))));
    108  1.1  mrg 	  else
    109  1.1  mrg 	    {
    110  1.1  mrg 	      __float128 r2 = 0, num, f;
    111  1.1  mrg 
    112  1.1  mrg 	      if (fabsq (__real__ x) >= FLT128_EPSILON * FLT128_EPSILON)
    113  1.1  mrg 		r2 = __real__ x * __real__ x;
    114  1.1  mrg 
    115  1.1  mrg 	      num = __imag__ x + 1;
    116  1.1  mrg 	      num = r2 + num * num;
    117  1.1  mrg 
    118  1.1  mrg 	      den = __imag__ x - 1;
    119  1.1  mrg 	      den = r2 + den * den;
    120  1.1  mrg 
    121  1.1  mrg 	      f = num / den;
    122  1.1  mrg 	      if (f < 0.5Q)
    123  1.1  mrg 		__imag__ res = 0.25Q * logq (f);
    124  1.1  mrg 	      else
    125  1.1  mrg 		{
    126  1.1  mrg 		  num = 4 * __imag__ x;
    127  1.1  mrg 		  __imag__ res = 0.25Q * log1pq (num / den);
    128  1.1  mrg 		}
    129  1.1  mrg 	    }
    130  1.1  mrg 	}
    131  1.1  mrg 
    132  1.1  mrg       math_check_force_underflow_complex (res);
    133  1.1  mrg     }
    134  1.1  mrg 
    135  1.1  mrg   return res;
    136  1.1  mrg }
    137