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