]> www.ginac.de Git - cln.git/blob - src/float/misc/cl_F_rational.cc
bef429c7eb646142ef7625a018200960e8325652
[cln.git] / src / float / misc / cl_F_rational.cc
1 // rational().
2
3 // General includes.
4 #include "cl_sysdep.h"
5
6 // Specification.
7 #include "cl_float.h"
8
9
10 // Implementation.
11
12 #include "cl_integer.h"
13 #include "cl_RA.h"
14
15 const cl_RA rational (const cl_F& x)
16 {
17   // Methode:
18   // Der mathematische Wert eines Float ist, wenn INTEGER-DECODE-FLOAT die
19   // drei Zahlen m,e,s (Mantisse, Exponent, Vorzeichen) liefert,
20   // = s * 2^e * m.
21   // n:=m. Falls s<0, setze n:=-m.
22   // Falls e>=0, ist (ash n e) das Ergebnis,
23   // sonst ist die rationale Zahl (/ n (ash 1 (- e))) das Ergebnis.
24         var cl_idecoded_float x_decoded = integer_decode_float(x);
25         var cl_I& m = x_decoded.mantissa;
26         var cl_I& e = x_decoded.exponent;
27         var cl_I& s = x_decoded.sign;
28         var cl_I n = (!minusp(s) ? m : -m);
29         if (!minusp(e))
30                 return ash(n,e);
31         else {
32 #if 0
33                 return I_posI_div_RA(n, ash(1,-e));
34 #else // spart ggT
35                 // n /= 0, -e > 0. Kürze mit ggT(n,2^(-e)) = 2^min(ord2(n),-e).
36                 // 0 < -e <= LF_exp_mid-LF_exp_low + intDsize*len < 2^32,
37                 var cl_I minus_e = -e;
38                 var uintL _e = cl_I_to_UL(minus_e); // daher kein Überlauf
39                 var uintL k = ord2(n);
40                 if (k >= _e)
41                         // Kürze mit 2^(-e).
42                         return ash(n,e);
43                 else
44                         // Kürze mit 2^k, 0 <= k < -e.
45                         return I_I_to_RT(ash(n,-(sintL)k),
46                                          ash(1,minus_e-UL_to_I(k)));
47 #endif
48         }
49 }