]> www.ginac.de Git - cln.git/blob - src/float/lfloat/cl_LF.h
Initial revision
[cln.git] / src / float / lfloat / cl_LF.h
1 // cl_LF internals
2
3 #ifndef _CL_LF_H
4 #define _CL_LF_H
5
6 #include "cl_number.h"
7 #include "cl_lfloat_class.h"
8 #include "cl_integer_class.h"
9
10 struct cl_heap_lfloat : cl_heap {
11         unsigned int len;       // length of mantissa (in digits)
12         int sign;               // sign (0 or -1)
13         uint32 expo;            // exponent
14         uintD data[1];          // mantissa
15 };
16
17 // Minimum number of mantissa digits,
18 // so that a LF has not fewer mantissa bits than a DF.
19   #define LF_minlen  ceiling(53,intDsize)
20 // Exponent.
21   #define LF_exp_low  1
22   #define LF_exp_mid  0x80000000UL
23   #define LF_exp_high 0xFFFFFFFFUL
24
25 inline cl_heap_lfloat* TheLfloat (cl_heap_lfloat* p)
26         { return p; }
27 inline cl_heap_lfloat* TheLfloat (const cl_number& obj)
28         { return (cl_heap_lfloat*)(obj.pointer); }
29
30
31 // Liefert zu einem Long-Float x : (futruncate x), ein LF.
32 // x wird von der 0 weg zur nächsten ganzen Zahl gerundet.
33 extern const cl_LF futruncate (const cl_LF& x);
34
35 // shorten(x,len) verkürzt ein Long-Float x auf gegebene Länge len
36 // und rundet dabei.
37 // > cl_LF x: ein Long-FLoat
38 // > uintC len: gewünschte Länge (>= LF_minlen, < TheLfloat(x)->len)
39 // < cl_LF ergebnis: verkürztes Long-Float
40 extern const cl_LF shorten (const cl_LF& x, uintC len);
41
42 // extend(x,len) verlängert ein Long-Float x auf gegebene Länge len.
43 // > cl_LF x: ein Long-FLoat
44 // > uintC len: gewünschte Länge (> TheLfloat(x)->len)
45 // < cl_LF ergebnis: verlängertes Long-Float
46 extern const cl_LF extend (const cl_LF& x, uintC len);
47
48 // LF_to_LF(x,len) wandelt ein Long-Float x in ein Long-Float gegebener Länge
49 // len um und rundet dabei nötigenfalls.
50 // > cl_LF x: ein Long-FLoat
51 // > uintC len: gewünschte Länge (>= LF_minlen)
52 // < cl_LF ergebnis: Long-Float gegebener Länge
53 extern const cl_LF LF_to_LF (const cl_LF& x, uintC len);
54
55 // GEN_LF_OP2(arg1,arg2,LF_OP,ergebnis_zuweisung)
56 // generates the body of a LF operation with two arguments.
57 // LF_OP is only executed once both arguments have been converted to the same
58 // float format (the longer one of arg1 and arg2). The result is then
59 // converted the shorter of the two float formats.
60 #define GEN_LF_OP2(arg1,arg2,LF_OP,ergebnis_zuweisung)  \
61 {                                                                       \
62         var uintC len1 = TheLfloat(arg1)->len;                          \
63         var uintC len2 = TheLfloat(arg2)->len;                          \
64         if (len1==len2) /* gleich -> direkt ausführen */                \
65                 return LF_OP(arg1,arg2);                                \
66         elif (len1>len2) /* -> arg2 auf die Länge von arg1 bringen */   \
67                 return shorten(LF_OP(arg1,extend(arg2,len1)),len2);     \
68         else /* (len1<len2) -> arg1 auf die Länge von arg2 bringen */   \
69                 return shorten(LF_OP(extend(arg1,len2),arg2),len1);     \
70 }
71
72 // Liefert zu zwei gleichlangen Long-Float x und y : (+ x y), ein LF.
73 // LF_LF_plus_LF(x)
74 extern const cl_LF LF_LF_plus_LF (const cl_LF& x, const cl_LF& y);
75
76 // Liefert zu zwei gleichlangen Long-Float x und y : (- x y), ein LF.
77 // LF_LF_minus_LF(x)
78 extern const cl_LF LF_LF_minus_LF (const cl_LF& x, const cl_LF& y);
79
80 // Use this macro if ALL of your cl_LF operations (+, -, *, /) in the
81 // rest of your file ALWAYS get two operands of the same precision.
82 #define ALL_cl_LF_OPERATIONS_SAME_PRECISION()  \
83                                                                         \
84 inline const cl_LF operator+ (const cl_LF& x, const cl_LF& y)           \
85 {                                                                       \
86         return LF_LF_plus_LF(x,y);                                      \
87 }                                                                       \
88                                                                         \
89 inline const cl_LF operator- (const cl_LF& x, const cl_LF& y)           \
90 {                                                                       \
91         return LF_LF_minus_LF(x,y);                                     \
92 }
93
94 // LF_to_I(x) wandelt ein Long-Float x, das eine ganze Zahl darstellt,
95 // in ein Integer um.
96 extern const cl_I cl_LF_to_I (const cl_LF& x);
97
98 // cl_I_to_LF(x,len) wandelt ein Integer x in ein Long-Float um und rundet dabei.
99 extern const cl_LF cl_I_to_LF (const cl_I& x, uintC len);
100
101 // cl_RA_to_LF(x,len) wandelt eine rationale Zahl x in ein Long-Float um
102 // und rundet dabei.
103 extern const cl_LF cl_RA_to_LF (const cl_RA& x, uintC len);
104
105 // cl_LF_I_mul(x,y) multipliziert ein Long-Float x und ein Integer y.
106 extern const cl_R cl_LF_I_mul (const cl_LF& x, const cl_I& y);
107
108 // cl_LF_I_div(x,y) dividiert ein Long-Float x durch ein Integer y.
109 extern const cl_LF cl_LF_I_div (const cl_LF& x, const cl_I& y);
110
111 // cl_I_LF_div(x,y) dividiert ein Integer x durch ein Long-Float y.
112 extern const cl_R cl_I_LF_div (const cl_I& x, const cl_LF& y);
113
114 // cl_LF_RA_mul(x,y) multipliziert ein Long-Float x und eine rationale Zahl y.
115 extern const cl_R cl_LF_RA_mul (const cl_LF& x, const cl_RA& y);
116
117 // cl_LF_RA_div(x,y) dividiert ein Long-Float x durch eine rationale Zahl y.
118 extern const cl_LF cl_LF_RA_div (const cl_LF& x, const cl_RA& y);
119
120 // cl_RA_LF_div(x,y) dividiert eine rationale Zahl x durch ein Long-Float y.
121 extern const cl_R cl_RA_LF_div (const cl_RA& x, const cl_LF& y);
122
123 // Vergrößert eine Long-Float-Länge n, so daß aus d = intDsize*n
124 // mindestens d+sqrt(d)+2 wird.
125 extern uintC cl_LF_len_incsqrt (uintC len);
126
127 // Vergrößert eine Long-Float-Länge n, so daß aus d = intDsize*n
128 // mindestens d+sqrt(d)+2+(LF_exp_len-1) wird.
129 extern uintC cl_LF_len_incsqrtx (uintC len);
130
131 // cl_LF_shortenrelative(x,y) tries to reduce the size of x, such that one
132 // wouldn't notice it when adding x to y. y must be /= 0. More precisely,
133 // this returns a float approximation of x, such that 1 ulp(x) < 1 ulp(y).
134 extern const cl_LF cl_LF_shortenrelative (const cl_LF& x, const cl_LF& y);
135
136 // cl_LF_shortenwith(x,y) tries to reduce the size of x, such that still
137 // 1 ulp(x) < y. y must be >0.
138 extern const cl_LF cl_LF_shortenwith (const cl_LF& x, const cl_LF& y);
139
140 #endif /* _CL_LF_H */