]> www.ginac.de Git - cln.git/blob - src/complex/algebraic/cl_C_sqrt.cc
46173823fd385618490ad2e542e853e0ec956d0e
[cln.git] / src / complex / algebraic / cl_C_sqrt.cc
1 // sqrt().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_complex.h"
8
9
10 // Implementation.
11
12 #include "cl_C.h"
13 #include "cl_real.h"
14
15 const cl_N sqrt (const cl_N& x)
16 {
17 // Methode:
18 // x reell -> Für x>=0 klar, für x<0: sqrt(-x)*i.
19 // x=a+bi ->
20 //   Bestimme r=abs(x)=sqrt(a*a+b*b).
21 //   Falls a>=0: Setze c:=sqrt((r+a)/2), d:=(b/(2*c) falls c>0, c falls c=0).
22 //   Falls a<0: Setze d:=sqrt((r-a)/2)*(1 falls b>=0, -1 falls b<0), c:=b/(2*d).
23 //   Damit ist c>=0, 2*c*d=b, c*c=(r+a)/2, d*d=(r-a)/2, c*c-d*d=a, c*c+d*d=r,
24 //   also c+di die gesuchte Wurzel.
25         if (realp(x)) {
26                 DeclareType(cl_R,x);
27                 if (!minusp(x))
28                         return sqrt(x);
29                 else
30                         return complex_C(0,sqrt(-x));
31         } else {
32                 DeclareType(cl_C,x);
33                 var const cl_R& a = realpart(x);
34                 var const cl_R& b = imagpart(x);
35                 var cl_R r = cl_hypot(a,b); // r = (abs x)
36                 if (!minusp(a)) {
37                         // a>=0
38                         var cl_R c = sqrt((r+a)/2);
39                         var cl_R d = (!zerop(c) ? b/(2*c) : c);
40                         return complex_C(c,d);
41                 } else {
42                         var cl_R d = sqrt((r-a)/2);
43                         if (minusp(b))
44                                 d = -d;
45                         var cl_R c = b/(2*d);
46                         return complex_C(c,d);
47                 }
48         }
49 }