]> www.ginac.de Git - cln.git/blob - include/cln/ffloat.h
a107a5e3bc36725253c1110967d7ba54a95c8ebf
[cln.git] / include / cln / ffloat.h
1 // Public single float operations.
2
3 #ifndef _CL_FFLOAT_H
4 #define _CL_FFLOAT_H
5
6 #include "cln/number.h"
7 #include "cln/ffloat_class.h"
8 #include "cln/integer_class.h"
9 #include "cln/float.h"
10
11 namespace cln {
12
13 CL_DEFINE_AS_CONVERSION(cl_FF)
14
15
16 // Liefert zu einem Single-Float x : (- x), ein FF.
17 extern const cl_FF operator- (const cl_FF& x);
18
19 // compare(x,y) vergleicht zwei Single-Floats x und y.
20 // Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
21 extern cl_signean compare (const cl_FF& x, const cl_FF& y);
22
23 // equal_hashcode(x) liefert einen equal-invarianten Hashcode für x.
24 extern uint32 equal_hashcode (const cl_FF& x);
25
26 inline bool operator== (const cl_FF& x, const cl_FF& y)
27         { return compare(x,y)==0; }
28 inline bool operator!= (const cl_FF& x, const cl_FF& y)
29         { return compare(x,y)!=0; }
30 inline bool operator<= (const cl_FF& x, const cl_FF& y)
31         { return compare(x,y)<=0; }
32 inline bool operator< (const cl_FF& x, const cl_FF& y)
33         { return compare(x,y)<0; }
34 inline bool operator>= (const cl_FF& x, const cl_FF& y)
35         { return compare(x,y)>=0; }
36 inline bool operator> (const cl_FF& x, const cl_FF& y)
37         { return compare(x,y)>0; }
38
39 // minusp(x) == (< x 0)
40 extern cl_boolean minusp (const cl_FF& x);
41
42 // zerop(x) stellt fest, ob ein Single-Float x = 0.0 ist.
43 extern cl_boolean zerop (const cl_FF& x);
44
45 // plusp(x) == (> x 0)
46 extern cl_boolean plusp (const cl_FF& x);
47
48 // Liefert zu zwei Single-Float x und y : (+ x y), ein FF.
49 extern const cl_FF operator+ (const cl_FF& x, const cl_FF& y);
50
51 // Liefert zu zwei Single-Float x und y : (- x y), ein FF.
52 extern const cl_FF operator- (const cl_FF& x, const cl_FF& y);
53
54 // Liefert zu zwei Single-Float x und y : (* x y), ein FF.
55 extern const cl_FF operator* (const cl_FF& x, const cl_FF& y);
56
57 // Liefert zu einem Single-Float x : (* x x), ein FF.
58 inline const cl_FF square (const cl_FF& x) { return x*x; }
59
60 // Liefert zu zwei Single-Float x und y : (/ x y), ein FF.
61 extern const cl_FF operator/ (const cl_FF& x, const cl_FF& y);
62
63 // Liefert zu einem Single-Float x>=0 : (sqrt x), ein FF.
64 extern const cl_FF sqrt (const cl_FF& x);
65
66 // recip(x) liefert (/ x), wo x ein Single-Float ist.
67 extern const cl_FF recip (const cl_FF& x);
68
69 // abs(x) liefert (abs x), wo x ein Single-Float ist.
70 extern const cl_FF abs (const cl_FF& x);
71
72
73 // (1+ x), wo x ein Single-Float ist.
74 inline const cl_FF plus1 (const cl_FF& x)
75 {
76         extern const cl_FF cl_I_to_FF (const cl_I&);
77         return x + cl_I_to_FF(cl_I(1));
78 }
79
80 // (1- x), wo x ein Single-Float ist.
81 inline const cl_FF minus1 (const cl_FF& x)
82 {
83         extern const cl_FF cl_I_to_FF (const cl_I&);
84         return x + cl_I_to_FF(cl_I(-1));
85 }
86
87
88 // ffloor(x) liefert (ffloor x), wo x ein FF ist.
89 extern const cl_FF ffloor (const cl_FF& x);
90
91 // fceiling(x) liefert (fceiling x), wo x ein FF ist.
92 extern const cl_FF fceiling (const cl_FF& x);
93
94 // ftruncate(x) liefert (ftruncate x), wo x ein FF ist.
95 extern const cl_FF ftruncate (const cl_FF& x);
96
97 // fround(x) liefert (fround x), wo x ein FF ist.
98 extern const cl_FF fround (const cl_FF& x);
99
100
101 // Return type for frounding operators.
102 // x / y  --> (q,r) with x = y*q+r.
103 struct cl_FF_fdiv_t {
104         cl_FF quotient;
105         cl_FF remainder;
106 // Constructor.
107         cl_FF_fdiv_t () {}
108         cl_FF_fdiv_t (const cl_FF& q, const cl_FF& r) : quotient(q), remainder(r) {}
109 };
110
111 // ffloor2(x) liefert (ffloor x), wo x ein FF ist.
112 inline const cl_FF_fdiv_t ffloor2 (const cl_FF& x)
113         { cl_FF q = ffloor(x); return cl_FF_fdiv_t(q,x-q); }
114
115 // fceiling2(x) liefert (fceiling x), wo x ein FF ist.
116 inline const cl_FF_fdiv_t fceiling2 (const cl_FF& x)
117         { cl_FF q = fceiling(x); return cl_FF_fdiv_t(q,x-q); }
118
119 // ftruncate2(x) liefert (ftruncate x), wo x ein FF ist.
120 inline const cl_FF_fdiv_t ftruncate2 (const cl_FF& x)
121         { cl_FF q = ftruncate(x); return cl_FF_fdiv_t(q,x-q); }
122
123 // fround2(x) liefert (fround x), wo x ein FF ist.
124 inline const cl_FF_fdiv_t fround2 (const cl_FF& x)
125         { cl_FF q = fround(x); return cl_FF_fdiv_t(q,x-q); }
126
127
128 // Return type for rounding operators.
129 // x / y  --> (q,r) with x = y*q+r.
130 struct cl_FF_div_t {
131         cl_I quotient;
132         cl_FF remainder;
133 // Constructor.
134         cl_FF_div_t () {}
135         cl_FF_div_t (const cl_I& q, const cl_FF& r) : quotient(q), remainder(r) {}
136 };
137
138 // floor2(x) liefert (floor x), wo x ein FF ist.
139 inline const cl_FF_div_t floor2 (const cl_FF& x)
140 {
141         extern const cl_I cl_FF_to_I (const cl_FF& x);
142         cl_FF q = ffloor(x);
143         return cl_FF_div_t(cl_FF_to_I(q),x-q);
144 }
145 inline const cl_I floor1 (const cl_FF& x)
146 {
147         extern const cl_I cl_FF_to_I (const cl_FF& x);
148         return cl_FF_to_I(ffloor(x));
149 }
150
151 // ceiling2(x) liefert (ceiling x), wo x ein FF ist.
152 inline const cl_FF_div_t ceiling2 (const cl_FF& x)
153 {
154         extern const cl_I cl_FF_to_I (const cl_FF& x);
155         cl_FF q = fceiling(x);
156         return cl_FF_div_t(cl_FF_to_I(q),x-q);
157 }
158 inline const cl_I ceiling1 (const cl_FF& x)
159 {
160         extern const cl_I cl_FF_to_I (const cl_FF& x);
161         return cl_FF_to_I(fceiling(x));
162 }
163
164 // truncate2(x) liefert (truncate x), wo x ein FF ist.
165 inline const cl_FF_div_t truncate2 (const cl_FF& x)
166 {
167         extern const cl_I cl_FF_to_I (const cl_FF& x);
168         cl_FF q = ftruncate(x);
169         return cl_FF_div_t(cl_FF_to_I(q),x-q);
170 }
171 inline const cl_I truncate1 (const cl_FF& x)
172 {
173         extern const cl_I cl_FF_to_I (const cl_FF& x);
174         return cl_FF_to_I(ftruncate(x));
175 }
176
177 // round2(x) liefert (round x), wo x ein FF ist.
178 inline const cl_FF_div_t round2 (const cl_FF& x)
179 {
180         extern const cl_I cl_FF_to_I (const cl_FF& x);
181         cl_FF q = fround(x);
182         return cl_FF_div_t(cl_FF_to_I(q),x-q);
183 }
184 inline const cl_I round1 (const cl_FF& x)
185 {
186         extern const cl_I cl_FF_to_I (const cl_FF& x);
187         return cl_FF_to_I(fround(x));
188 }
189
190 // floor2(x,y) liefert (floor x y).
191 extern const cl_FF_div_t floor2 (const cl_FF& x, const cl_FF& y);
192 inline const cl_I floor1 (const cl_FF& x, const cl_FF& y) { return floor1(x/y); }
193
194 // ceiling2(x,y) liefert (ceiling x y).
195 extern const cl_FF_div_t ceiling2 (const cl_FF& x, const cl_FF& y);
196 inline const cl_I ceiling1 (const cl_FF& x, const cl_FF& y) { return ceiling1(x/y); }
197
198 // truncate2(x,y) liefert (truncate x y).
199 extern const cl_FF_div_t truncate2 (const cl_FF& x, const cl_FF& y);
200 inline const cl_I truncate1 (const cl_FF& x, const cl_FF& y) { return truncate1(x/y); }
201
202 // round2(x,y) liefert (round x y).
203 extern const cl_FF_div_t round2 (const cl_FF& x, const cl_FF& y);
204 inline const cl_I round1 (const cl_FF& x, const cl_FF& y) { return round1(x/y); }
205
206
207 // Return type for decode_float:
208 struct decoded_ffloat {
209         cl_FF mantissa;
210         cl_I exponent;
211         cl_FF sign;
212 // Constructor.
213         decoded_ffloat () {}
214         decoded_ffloat (const cl_FF& m, const cl_I& e, const cl_FF& s) : mantissa(m), exponent(e), sign(s) {}
215 };
216
217 // decode_float(x) liefert zu einem Float x: (decode-float x).
218 // x = 0.0 liefert (0.0, 0, 1.0).
219 // x = (-1)^s * 2^e * m liefert ((-1)^0 * 2^0 * m, e als Integer, (-1)^s).
220 extern const decoded_ffloat decode_float (const cl_FF& x);
221
222 // float_exponent(x) liefert zu einem Float x:
223 // den Exponenten von (decode-float x).
224 // x = 0.0 liefert 0.
225 // x = (-1)^s * 2^e * m liefert e.
226 extern sintL float_exponent (const cl_FF& x);
227
228 // float_radix(x) liefert (float-radix x), wo x ein Float ist.
229 inline sintL float_radix (const cl_FF& x)
230 {
231         (void)x; // unused x
232         return 2;
233 }
234
235 // float_sign(x) liefert (float-sign x), wo x ein Float ist.
236 extern const cl_FF float_sign (const cl_FF& x);
237
238 // float_digits(x) liefert (float-digits x), wo x ein Float ist.
239 // < ergebnis: ein uintL >0
240 extern uintL float_digits (const cl_FF& x);
241
242 // float_precision(x) liefert (float-precision x), wo x ein Float ist.
243 // < ergebnis: ein uintL >=0
244 extern uintL float_precision (const cl_FF& x);
245
246
247 // integer_decode_float(x) liefert zu einem Float x: (integer-decode-float x).
248 // x = 0.0 liefert (0, 0, 1).
249 // x = (-1)^s * 2^e * m bei Float-Precision p liefert
250 //   (Mantisse 2^p * m als Integer, e-p als Integer, (-1)^s als Fixnum).
251 extern const cl_idecoded_float integer_decode_float (const cl_FF& x);
252
253
254 // scale_float(x,delta) liefert x*2^delta, wo x ein FF ist.
255 extern const cl_FF scale_float (const cl_FF& x, sintL delta);
256 extern const cl_FF scale_float (const cl_FF& x, const cl_I& delta);
257
258
259 // max(x,y) liefert (max x y), wo x und y Floats sind.
260 extern const cl_FF max (const cl_FF& x, const cl_FF& y);
261
262 // min(x,y) liefert (min x y), wo x und y Floats sind.
263 extern const cl_FF min (const cl_FF& x, const cl_FF& y);
264
265 // signum(x) liefert (signum x), wo x ein Float ist.
266 extern const cl_FF signum (const cl_FF& x);
267
268
269 // Konversion zu einem C "float".
270 extern float float_approx (const cl_FF& x);
271
272 // Konversion zu einem C "double".
273 extern double double_approx (const cl_FF& x);
274
275
276 #ifdef WANT_OBFUSCATING_OPERATORS
277 // This could be optimized to use in-place operations.
278 inline cl_FF& operator+= (cl_FF& x, const cl_FF& y) { return x = x + y; }
279 inline cl_FF& operator++ /* prefix */ (cl_FF& x) { return x = plus1(x); }
280 inline void operator++ /* postfix */ (cl_FF& x, int dummy) { (void)dummy; x = plus1(x); }
281 inline cl_FF& operator-= (cl_FF& x, const cl_FF& y) { return x = x - y; }
282 inline cl_FF& operator-- /* prefix */ (cl_FF& x) { return x = minus1(x); }
283 inline void operator-- /* postfix */ (cl_FF& x, int dummy) { (void)dummy; x = minus1(x); }
284 inline cl_FF& operator*= (cl_FF& x, const cl_FF& y) { return x = x * y; }
285 inline cl_FF& operator/= (cl_FF& x, const cl_FF& y) { return x = x / y; }
286 #endif
287
288
289 CL_REQUIRE(cl_ieee)
290 /* */
291
292
293 // Runtime typing support.
294 extern cl_class cl_class_ffloat;
295 #ifdef CL_WIDE_POINTERS
296 CL_FORCE_LINK(cl_FF_classes_dummy, cl_class_ffloat)
297 #endif
298
299
300 // Debugging support.
301 #ifdef CL_DEBUG
302 extern int cl_FF_debug_module;
303 CL_FORCE_LINK(cl_FF_debug_dummy, cl_FF_debug_module)
304 #endif
305
306 }  // namespace cln
307
308 #endif /* _CL_FFLOAT_H */