xref: /haiku/src/system/libroot/posix/glibc/arch/generic/s_csqrtl.c (revision f504f61099b010fbfa94b1cc63d2e9072c7f7185)
15acbf1f5SJérôme Duval /* Complex square root of long double value.
25acbf1f5SJérôme Duval    Copyright (C) 1997, 1998 Free Software Foundation, Inc.
35acbf1f5SJérôme Duval    This file is part of the GNU C Library.
45acbf1f5SJérôme Duval    Based on an algorithm by Stephen L. Moshier <moshier@world.std.com>.
55acbf1f5SJérôme Duval    Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
65acbf1f5SJérôme Duval 
75acbf1f5SJérôme Duval    The GNU C Library is free software; you can redistribute it and/or
85acbf1f5SJérôme Duval    modify it under the terms of the GNU Lesser General Public
95acbf1f5SJérôme Duval    License as published by the Free Software Foundation; either
105acbf1f5SJérôme Duval    version 2.1 of the License, or (at your option) any later version.
115acbf1f5SJérôme Duval 
125acbf1f5SJérôme Duval    The GNU C Library is distributed in the hope that it will be useful,
135acbf1f5SJérôme Duval    but WITHOUT ANY WARRANTY; without even the implied warranty of
145acbf1f5SJérôme Duval    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
155acbf1f5SJérôme Duval    Lesser General Public License for more details.
165acbf1f5SJérôme Duval 
175acbf1f5SJérôme Duval    You should have received a copy of the GNU Lesser General Public
185acbf1f5SJérôme Duval    License along with the GNU C Library; if not, write to the Free
195acbf1f5SJérôme Duval    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
205acbf1f5SJérôme Duval    02111-1307 USA.  */
215acbf1f5SJérôme Duval 
225acbf1f5SJérôme Duval #include <complex.h>
235acbf1f5SJérôme Duval #include <math.h>
245acbf1f5SJérôme Duval 
255acbf1f5SJérôme Duval #include "math_private.h"
265acbf1f5SJérôme Duval 
275acbf1f5SJérôme Duval 
285acbf1f5SJérôme Duval __complex__ long double
__csqrtl(__complex__ long double x)295acbf1f5SJérôme Duval __csqrtl (__complex__ long double x)
305acbf1f5SJérôme Duval {
315acbf1f5SJérôme Duval   __complex__ long double res;
325acbf1f5SJérôme Duval   int rcls = fpclassify (__real__ x);
335acbf1f5SJérôme Duval   int icls = fpclassify (__imag__ x);
345acbf1f5SJérôme Duval 
355acbf1f5SJérôme Duval   if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
365acbf1f5SJérôme Duval     {
375acbf1f5SJérôme Duval       if (icls == FP_INFINITE)
385acbf1f5SJérôme Duval 	{
395acbf1f5SJérôme Duval 	  __real__ res = HUGE_VALL;
405acbf1f5SJérôme Duval 	  __imag__ res = __imag__ x;
415acbf1f5SJérôme Duval 	}
425acbf1f5SJérôme Duval       else if (rcls == FP_INFINITE)
435acbf1f5SJérôme Duval 	{
445acbf1f5SJérôme Duval 	  if (__real__ x < 0.0)
455acbf1f5SJérôme Duval 	    {
46*f504f610SAugustin Cavalier 	      __real__ res = icls == FP_NAN ? nanl ("") : 0;
47*f504f610SAugustin Cavalier 	      __imag__ res = copysignl (HUGE_VALL, __imag__ x);
485acbf1f5SJérôme Duval 	    }
495acbf1f5SJérôme Duval 	  else
505acbf1f5SJérôme Duval 	    {
515acbf1f5SJérôme Duval 	      __real__ res = __real__ x;
525acbf1f5SJérôme Duval 	      __imag__ res = (icls == FP_NAN
53*f504f610SAugustin Cavalier 			      ? nanl ("") : copysignl (0.0, __imag__ x));
545acbf1f5SJérôme Duval 	    }
555acbf1f5SJérôme Duval 	}
565acbf1f5SJérôme Duval       else
575acbf1f5SJérôme Duval 	{
58*f504f610SAugustin Cavalier 	  __real__ res = nanl ("");
59*f504f610SAugustin Cavalier 	  __imag__ res = nanl ("");
605acbf1f5SJérôme Duval 	}
615acbf1f5SJérôme Duval     }
625acbf1f5SJérôme Duval   else
635acbf1f5SJérôme Duval     {
645acbf1f5SJérôme Duval       if (icls == FP_ZERO)
655acbf1f5SJérôme Duval 	{
665acbf1f5SJérôme Duval 	  if (__real__ x < 0.0)
675acbf1f5SJérôme Duval 	    {
685acbf1f5SJérôme Duval 	      __real__ res = 0.0;
69*f504f610SAugustin Cavalier 	      __imag__ res = copysignl (sqrtl (-__real__ x),
705acbf1f5SJérôme Duval 					  __imag__ x);
715acbf1f5SJérôme Duval 	    }
725acbf1f5SJérôme Duval 	  else
735acbf1f5SJérôme Duval 	    {
74*f504f610SAugustin Cavalier 	      __real__ res = fabsl (sqrtl (__real__ x));
75*f504f610SAugustin Cavalier 	      __imag__ res = copysignl (0.0, __imag__ x);
765acbf1f5SJérôme Duval 	    }
775acbf1f5SJérôme Duval 	}
785acbf1f5SJérôme Duval       else if (rcls == FP_ZERO)
795acbf1f5SJérôme Duval 	{
80*f504f610SAugustin Cavalier 	  long double r = sqrtl (0.5 * fabsl (__imag__ x));
815acbf1f5SJérôme Duval 
82*f504f610SAugustin Cavalier 	  __real__ res = copysignl (r, __imag__ x);
835acbf1f5SJérôme Duval 	  __imag__ res = r;
845acbf1f5SJérôme Duval 	}
855acbf1f5SJérôme Duval       else
865acbf1f5SJérôme Duval 	{
875acbf1f5SJérôme Duval 	  long double d, r, s;
885acbf1f5SJérôme Duval 
89*f504f610SAugustin Cavalier 	  d = hypotl (__real__ x, __imag__ x);
905acbf1f5SJérôme Duval 	  /* Use the identity   2  Re res  Im res = Im x
915acbf1f5SJérôme Duval 	     to avoid cancellation error in  d +/- Re x.  */
925acbf1f5SJérôme Duval 	  if (__real__ x > 0)
935acbf1f5SJérôme Duval 	    {
94*f504f610SAugustin Cavalier 	      r = sqrtl (0.5L * d + 0.5L * __real__ x);
955acbf1f5SJérôme Duval 	      s = (0.5L * __imag__ x) / r;
965acbf1f5SJérôme Duval 	    }
975acbf1f5SJérôme Duval 	  else
985acbf1f5SJérôme Duval 	    {
99*f504f610SAugustin Cavalier 	      s = sqrtl (0.5L * d - 0.5L * __real__ x);
1005acbf1f5SJérôme Duval 	      r = fabsl ((0.5L * __imag__ x) / s);
1015acbf1f5SJérôme Duval 	    }
1025acbf1f5SJérôme Duval 
1035acbf1f5SJérôme Duval 	  __real__ res = r;
104*f504f610SAugustin Cavalier 	  __imag__ res = copysignl (s, __imag__ x);
1055acbf1f5SJérôme Duval 	}
1065acbf1f5SJérôme Duval     }
1075acbf1f5SJérôme Duval 
1085acbf1f5SJérôme Duval   return res;
1095acbf1f5SJérôme Duval }
1105acbf1f5SJérôme Duval weak_alias (__csqrtl, csqrtl)
111