]> www.ginac.de Git - cln.git/blob - src/real/misc/cl_R_expt.cc
4d0e013a7cdd693f6e066ecd8611946c38fffefa
[cln.git] / src / real / misc / cl_R_expt.cc
1 // expt().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_real.h"
8
9
10 // Implementation.
11
12 #include "cl_R.h"
13 #include "cl_rational.h"
14 #include "cl_integer.h"
15
16 // Methode:
17 // Für y>0:
18 //   a:=x, b:=y.
19 //   Solange b gerade, setze a:=a*a, b:=b/2. [a^b bleibt invariant, = x^y.]
20 //   c:=a.
21 //   Solange b:=floor(b/2) >0 ist,
22 //     setze a:=a*a, und falls b ungerade, setze c:=a*c.
23 //   Ergebnis c.
24 // Für y=0: Ergebnis 1.
25 // Für y<0: (/ (expt x (- y))).
26
27 // Assume y>0.
28 inline const cl_R expt_pos (const cl_R& x, uintL y)
29 {
30         if (rationalp(x)) {
31                 DeclareType(cl_RA,x);
32                 return expt(x,y); // x rational -> schnellere Routine
33         } else {
34                 DeclareType(cl_F,x);
35                 var cl_F a = x;
36                 var uintL b = y;
37                 while (!(b % 2)) { a = square(a); b = b >> 1; }
38                 var cl_F c = a;
39                 until (b == 1)
40                   { b = b >> 1;
41                     a = square(a);
42                     if (b % 2) { c = a * c; }
43                   }
44                 return c;
45         }
46 }
47
48 const cl_R expt (const cl_R& x, sintL 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_R z = expt_pos(x,abs_y); // (expt x (abs y))
53         return (y<0 ? recip(z) : z); // evtl. noch Kehrwert nehmen
54 }