]> www.ginac.de Git - cln.git/blob - src/complex/misc/cl_C_expt.cc
* tests/Makefile.in: MinGW support for make check
[cln.git] / src / complex / misc / cl_C_expt.cc
1 // expt().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cln/complex.h"
8
9
10 // Implementation.
11
12 #include "cl_C.h"
13 #include "cln/real.h"
14
15 namespace cln {
16
17 // Methode:
18 // Für y>0:
19 //   a:=x, b:=y.
20 //   Solange b gerade, setze a:=a*a, b:=b/2. [a^b bleibt invariant, = x^y.]
21 //   c:=a.
22 //   Solange b:=floor(b/2) >0 ist,
23 //     setze a:=a*a, und falls b ungerade, setze c:=a*c.
24 //   Ergebnis c.
25 // Für y=0: Ergebnis 1.
26 // Für y<0: (/ (expt x (- y))).
27
28 // Assume y>0.
29 inline const cl_N expt_pos (const cl_N& x, uintL y)
30 {
31         var cl_N a = x;
32         var uintL b = y;
33         while (!(b % 2)) { a = square(a); b = b >> 1; }
34         var cl_N c = a;
35         until (b == 1)
36           { b = b >> 1;
37             a = square(a);
38             if (b % 2) { c = a * c; }
39           }
40         return c;
41 }
42
43 const cl_N expt (const cl_N& x, sintL y)
44 {
45         if (realp(x)) {
46                 DeclareType(cl_R,x);
47                 // x reell -> schnellere Routine
48                 return expt(x,y);
49         }
50         if (y==0) { return 1; } // y=0 -> Ergebnis 1
51         var uintL abs_y = (y<0 ? (uintL)(-y) : y); // Betrag von y nehmen
52         var cl_N z = expt_pos(x,abs_y); // (expt x (abs y))
53         return (y<0 ? recip(z) : z); // evtl. noch Kehrwert nehmen
54 }
55
56 }  // namespace cln