]> www.ginac.de Git - cln.git/blob - include/cln/float.h
Get rid CL_REQUIRE/CL_PROVIDE(cl_F_mostpos), it is not really necessary.
[cln.git] / include / cln / float.h
1 // Public float operations.
2
3 #ifndef _CL_FLOAT_H
4 #define _CL_FLOAT_H
5
6 #include "cln/number.h"
7 #include "cln/float_class.h"
8 #include "cln/floatformat.h"
9 #include "cln/random.h"
10 #include "cln/integer_class.h"
11 #include "cln/sfloat_class.h"
12 #include "cln/ffloat_class.h"
13 #include "cln/dfloat_class.h"
14 #include "cln/lfloat_class.h"
15 #include "cln/exception.h"
16
17 namespace cln {
18
19 CL_DEFINE_AS_CONVERSION(cl_F)
20
21
22 // Return type for integer_decode_float:
23 struct cl_idecoded_float {
24         cl_I mantissa;
25         cl_I exponent;
26         cl_I sign;
27 // Constructor.
28         cl_idecoded_float () {}
29         cl_idecoded_float (const cl_I& m, const cl_I& e, const cl_I& s) : mantissa(m), exponent(e), sign(s) {}
30 };
31
32
33 // zerop(x) testet, ob (= x 0).
34 extern bool zerop (const cl_F& x);
35
36 // minusp(x) testet, ob (< x 0).
37 extern bool minusp (const cl_F& x);
38
39 // plusp(x) testet, ob (> x 0).
40 extern bool plusp (const cl_F& x);
41
42
43 // cl_F_to_SF(x) wandelt ein Float x in ein Short-Float um und rundet dabei.
44 extern const cl_SF cl_F_to_SF (const cl_F& x);
45
46 // cl_F_to_FF(x) wandelt ein Float x in ein Single-Float um und rundet dabei.
47 extern const cl_FF cl_F_to_FF (const cl_F& x);
48
49 // cl_F_to_DF(x) wandelt ein Float x in ein Double-Float um und rundet dabei.
50 extern const cl_DF cl_F_to_DF (const cl_F& x);
51
52 // cl_F_to_LF(x,len) wandelt ein Float x in ein Long-Float mit len Digits um
53 // und rundet dabei.
54 // > uintC len: gewünschte Anzahl Digits, >=LF_minlen
55 extern const cl_LF cl_F_to_LF (const cl_F& x, uintC len);
56
57
58 // The default float format used when converting rational numbers to floats.
59 extern float_format_t default_float_format;
60
61 // Returns the smallest float format which guarantees at least n decimal digits
62 // in the mantissa (after the decimal point).
63 extern float_format_t float_format (uintE n);
64
65 // cl_float(x,y) wandelt ein Float x in das Float-Format des Floats y um
66 // und rundet dabei nötigenfalls.
67 // > x,y: Floats
68 // < ergebnis: (float x y)
69 extern const cl_F cl_float (const cl_F& x, const cl_F& y);
70
71 // cl_float(x,f) wandelt ein Float x in das Float-Format f um
72 // und rundet dabei nötigenfalls.
73 // > x: ein Float
74 // > f: eine Float-Format-Spezifikation
75 // < ergebnis: (float x f)
76 extern const cl_F cl_float (const cl_F& x, float_format_t f);
77
78 // cl_float(x) wandelt eine reelle Zahl x in ein Float um
79 // und rundet dabei nötigenfalls.
80 // > x: eine reelle Zahl
81 // < ergebnis: (float x)
82 // Abhängig von default_float_format.
83 inline const cl_F cl_float (const cl_F& x) { return x; }
84
85 // cl_float(x,y) wandelt ein Integer x in das Float-Format des Floats y um
86 // und rundet dabei nötigenfalls.
87 // > x: ein Integer
88 // > y: ein Float
89 // < ergebnis: (float x y)
90 extern const cl_F cl_float (const cl_I& x, const cl_F& y);
91
92 // cl_float(x,y) wandelt ein Integer x in das Float-Format f um
93 // und rundet dabei nötigenfalls.
94 // > x: ein Integer
95 // > f: eine Float-Format-Spezifikation
96 // < ergebnis: (float x f)
97 extern const cl_F cl_float (const cl_I& x, float_format_t f);
98
99 // cl_float(x) wandelt ein Integer x in ein Float um und rundet dabei.
100 // > x: ein Integer
101 // < ergebnis: (float x)
102 // Abhängig von default_float_format.
103 extern const cl_F cl_float (const cl_I& x);
104
105 // cl_float(x,y) wandelt eine rationale Zahl x in das Float-Format des
106 // Floats y um und rundet dabei nötigenfalls.
107 // > x: eine rationale Zahl
108 // > y: ein Float
109 // < ergebnis: (float x y)
110 extern const cl_F cl_float (const cl_RA& x, const cl_F& y);
111
112 // cl_float(x,y) wandelt eine rationale Zahl x in das Float-Format f um
113 // und rundet dabei nötigenfalls.
114 // > x: eine rationale Zahl
115 // > f: eine Float-Format-Spezifikation
116 // < ergebnis: (float x f)
117 extern const cl_F cl_float (const cl_RA& x, float_format_t f);
118
119 // cl_float(x) wandelt eine rationale Zahl x in ein Float um und rundet dabei.
120 // > x: eine rationale Zahl
121 // < ergebnis: (float x)
122 // Abhängig von default_float_format.
123 extern const cl_F cl_float (const cl_RA& x);
124
125 // The C++ compilers are not clever enough to guess this:
126 inline const cl_F cl_float (int x, const cl_F& y)
127         { return cl_float(cl_I(x),y); }
128 inline const cl_F cl_float (unsigned int x, const cl_F& y)
129         { return cl_float(cl_I(x),y); }
130 inline const cl_F cl_float (int x, float_format_t y)
131         { return cl_float(cl_I(x),y); }
132 inline const cl_F cl_float (unsigned int x, float_format_t y)
133         { return cl_float(cl_I(x),y); }
134 inline const cl_F cl_float (int x)
135         { return cl_float(cl_I(x)); }
136 inline const cl_F cl_float (unsigned int x)
137         { return cl_float(cl_I(x)); }
138 // The C++ compilers could hardly guess the following:
139 inline const cl_F cl_float (float x, const cl_F& y)
140         { return cl_float(cl_FF(x),y); }
141 inline const cl_F cl_float (double x, const cl_F& y)
142         { return cl_float(cl_DF(x),y); }
143 inline const cl_F cl_float (float x, float_format_t y)
144         { return cl_float(cl_FF(x),y); }
145 inline const cl_F cl_float (double x, float_format_t y)
146         { return cl_float(cl_DF(x),y); }
147 inline const cl_F cl_float (float x)
148         { return cl_float(cl_FF(x)); }
149 inline const cl_F cl_float (double x)
150         { return cl_float(cl_DF(x)); }
151
152
153 // Liefert (- x), wo x ein Float ist.
154 extern const cl_F operator- (const cl_F& x);
155
156 // Liefert (+ x y), wo x und y Floats sind.
157 extern const cl_F operator+ (const cl_F& x, const cl_F& y);
158 // The C++ compilers could hardly guess the following:
159 inline const cl_F operator+ (const cl_RA& x, const cl_F& y)
160         { return cl_float(x,y) + y; }
161 inline const cl_F operator+ (const cl_I& x, const cl_F& y)
162         { return cl_float(x,y) + y; }
163 inline const cl_F operator+ (const cl_F& x, const cl_RA& y)
164         { return x + cl_float(y,x); }
165 inline const cl_F operator+ (const cl_F& x, const cl_I& y)
166         { return x + cl_float(y,x); }
167 // Dem C++-Compiler muß man nun auch das Folgende sagen:
168 inline const cl_F operator+ (const int x, const cl_F& y)
169         { return cl_I(x) + y; }
170 inline const cl_F operator+ (const unsigned int x, const cl_F& y)
171         { return cl_I(x) + y; }
172 inline const cl_F operator+ (const long x, const cl_F& y)
173         { return cl_I(x) + y; }
174 inline const cl_F operator+ (const unsigned long x, const cl_F& y)
175         { return cl_I(x) + y; }
176 #ifdef HAVE_LONGLONG
177 inline const cl_F operator+ (const long long x, const cl_F& y)
178         { return cl_I(x) + y; }
179 inline const cl_F operator+ (const unsigned long long x, const cl_F& y)
180         { return cl_I(x) + y; }
181 #endif
182 inline const cl_F operator+ (const float x, const cl_F& y)
183         { return cl_F(x) + y; }
184 inline const cl_F operator+ (const double x, const cl_F& y)
185         { return cl_F(x) + y; }
186 inline const cl_F operator+ (const cl_F& x, const int y)
187         { return x + cl_I(y); }
188 inline const cl_F operator+ (const cl_F& x, const unsigned int y)
189         { return x + cl_I(y); }
190 inline const cl_F operator+ (const cl_F& x, const long y)
191         { return x + cl_I(y); }
192 inline const cl_F operator+ (const cl_F& x, const unsigned long y)
193         { return x + cl_I(y); }
194 #ifdef HAVE_LONGLONG
195 inline const cl_F operator+ (const cl_F& x, const long long y)
196         { return x + cl_I(y); }
197 inline const cl_F operator+ (const cl_F& x, const unsigned long long y)
198         { return x + cl_I(y); }
199 #endif
200 inline const cl_F operator+ (const cl_F& x, const float y)
201         { return x + cl_F(y); }
202 inline const cl_F operator+ (const cl_F& x, const double y)
203         { return x + cl_F(y); }
204
205 // Liefert (- x y), wo x und y Floats sind.
206 extern const cl_F operator- (const cl_F& x, const cl_F& y);
207 // The C++ compilers could hardly guess the following:
208 inline const cl_F operator- (const cl_RA& x, const cl_F& y)
209         { return cl_float(x,y) - y; }
210 inline const cl_F operator- (const cl_I& x, const cl_F& y)
211         { return cl_float(x,y) - y; }
212 inline const cl_F operator- (const cl_F& x, const cl_RA& y)
213         { return x - cl_float(y,x); }
214 inline const cl_F operator- (const cl_F& x, const cl_I& y)
215         { return x - cl_float(y,x); }
216 // Dem C++-Compiler muß man nun auch das Folgende sagen:
217 inline const cl_F operator- (const int x, const cl_F& y)
218         { return cl_I(x) - y; }
219 inline const cl_F operator- (const unsigned int x, const cl_F& y)
220         { return cl_I(x) - y; }
221 inline const cl_F operator- (const long x, const cl_F& y)
222         { return cl_I(x) - y; }
223 inline const cl_F operator- (const unsigned long x, const cl_F& y)
224         { return cl_I(x) - y; }
225 #ifdef HAVE_LONGLONG
226 inline const cl_F operator- (const long long x, const cl_F& y)
227         { return cl_I(x) - y; }
228 inline const cl_F operator- (const unsigned long long x, const cl_F& y)
229         { return cl_I(x) - y; }
230 #endif
231 inline const cl_F operator- (const float x, const cl_F& y)
232         { return cl_F(x) - y; }
233 inline const cl_F operator- (const double x, const cl_F& y)
234         { return cl_F(x) - y; }
235 inline const cl_F operator- (const cl_F& x, const int y)
236         { return x - cl_I(y); }
237 inline const cl_F operator- (const cl_F& x, const unsigned int y)
238         { return x - cl_I(y); }
239 inline const cl_F operator- (const cl_F& x, const long y)
240         { return x - cl_I(y); }
241 inline const cl_F operator- (const cl_F& x, const unsigned long y)
242         { return x - cl_I(y); }
243 #ifdef HAVE_LONGLONG
244 inline const cl_F operator- (const cl_F& x, const long long y)
245         { return x - cl_I(y); }
246 inline const cl_F operator- (const cl_F& x, const unsigned long long y)
247         { return x - cl_I(y); }
248 #endif
249 inline const cl_F operator- (const cl_F& x, const float y)
250         { return x - cl_F(y); }
251 inline const cl_F operator- (const cl_F& x, const double y)
252         { return x - cl_F(y); }
253
254 // Liefert (* x y), wo x und y Floats sind.
255 extern const cl_F operator* (const cl_F& x, const cl_F& y);
256 // Spezialfall x oder y Integer oder rationale Zahl.
257 inline const cl_R operator* (const cl_F& x, const cl_I& y)
258 {
259         extern const cl_R cl_F_I_mul (const cl_F&, const cl_I&);
260         return cl_F_I_mul(x,y);
261 }
262 inline const cl_R operator* (const cl_I& x, const cl_F& y)
263 {
264         extern const cl_R cl_F_I_mul (const cl_F&, const cl_I&);
265         return cl_F_I_mul(y,x);
266 }
267 inline const cl_R operator* (const cl_F& x, const cl_RA& y)
268 {
269         extern const cl_R cl_F_RA_mul (const cl_F&, const cl_RA&);
270         return cl_F_RA_mul(x,y);
271 }
272 inline const cl_R operator* (const cl_RA& x, const cl_F& y)
273 {
274         extern const cl_R cl_F_RA_mul (const cl_F&, const cl_RA&);
275         return cl_F_RA_mul(y,x);
276 }
277 // Dem C++-Compiler muß man nun auch das Folgende sagen:
278 inline const cl_R operator* (const int x, const cl_F& y)
279         { return cl_I(x) * y; }
280 inline const cl_R operator* (const unsigned int x, const cl_F& y)
281         { return cl_I(x) * y; }
282 inline const cl_R operator* (const long x, const cl_F& y)
283         { return cl_I(x) * y; }
284 inline const cl_R operator* (const unsigned long x, const cl_F& y)
285         { return cl_I(x) * y; }
286 #ifdef HAVE_LONGLONG
287 inline const cl_R operator* (const long long x, const cl_F& y)
288         { return cl_I(x) * y; }
289 inline const cl_R operator* (const unsigned long long x, const cl_F& y)
290         { return cl_I(x) * y; }
291 #endif
292 inline const cl_F operator* (const float x, const cl_F& y)
293         { return cl_F(x) * y; }
294 inline const cl_F operator* (const double x, const cl_F& y)
295         { return cl_F(x) * y; }
296 inline const cl_R operator* (const cl_F& x, const int y)
297         { return x * cl_I(y); }
298 inline const cl_R operator* (const cl_F& x, const unsigned int y)
299         { return x * cl_I(y); }
300 inline const cl_R operator* (const cl_F& x, const long y)
301         { return x * cl_I(y); }
302 inline const cl_R operator* (const cl_F& x, const unsigned long y)
303         { return x * cl_I(y); }
304 #ifdef HAVE_LONGLONG
305 inline const cl_R operator* (const cl_F& x, const long long y)
306         { return x * cl_I(y); }
307 inline const cl_R operator* (const cl_F& x, const unsigned long long y)
308         { return x * cl_I(y); }
309 #endif
310 inline const cl_F operator* (const cl_F& x, const float y)
311         { return x * cl_F(y); }
312 inline const cl_F operator* (const cl_F& x, const double y)
313         { return x * cl_F(y); }
314
315 // Liefert (* x x), wo x ein Float ist.
316 extern const cl_F square (const cl_F& x);
317
318 // Liefert (/ x y), wo x und y Floats sind.
319 extern const cl_F operator/ (const cl_F& x, const cl_F& y);
320 // Liefert (/ x y), wo x und y ein Float und eine rationale Zahl sind.
321 extern const cl_F operator/ (const cl_F& x, const cl_RA& y);
322 extern const cl_F operator/ (const cl_F& x, const cl_I& y);
323 extern const cl_R operator/ (const cl_RA& x, const cl_F& y);
324 extern const cl_R operator/ (const cl_I& x, const cl_F& y);
325 // The C++ compilers could hardly guess the following:
326 inline const cl_F operator/ (const cl_F& x, const int y)
327         { return x / cl_I(y); }
328 inline const cl_F operator/ (const cl_F& x, const unsigned int y)
329         { return x / cl_I(y); }
330 inline const cl_F operator/ (const cl_F& x, const long y)
331         { return x / cl_I(y); }
332 inline const cl_F operator/ (const cl_F& x, const unsigned long y)
333         { return x / cl_I(y); }
334 #ifdef HAVE_LONGLONG
335 inline const cl_F operator/ (const cl_F& x, const long long y)
336         { return x / cl_I(y); }
337 inline const cl_F operator/ (const cl_F& x, const unsigned long long y)
338         { return x / cl_I(y); }
339 #endif
340 inline const cl_F operator/ (const cl_F& x, const float y)
341         { return x / cl_F(y); }
342 inline const cl_F operator/ (const cl_F& x, const double y)
343         { return x / cl_F(y); }
344 inline const cl_R operator/ (const int x, const cl_F& y)
345         { return cl_I(x) / y; }
346 inline const cl_R operator/ (const unsigned int x, const cl_F& y)
347         { return cl_I(x) / y; }
348 inline const cl_R operator/ (const long x, const cl_F& y)
349         { return cl_I(x) / y; }
350 inline const cl_R operator/ (const unsigned long x, const cl_F& y)
351         { return cl_I(x) / y; }
352 #ifdef HAVE_LONGLONG
353 inline const cl_R operator/ (const long long x, const cl_F& y)
354         { return cl_I(x) / y; }
355 inline const cl_R operator/ (const unsigned long long x, const cl_F& y)
356         { return cl_I(x) / y; }
357 #endif
358 inline const cl_F operator/ (const float x, const cl_F& y)
359         { return cl_F(x) / y; }
360 inline const cl_F operator/ (const double x, const cl_F& y)
361         { return cl_F(x) / y; }
362
363 // Liefert (abs x), wo x ein Float ist.
364 extern const cl_F abs (const cl_F& x);
365
366 // Liefert zu einem Float x>=0 : (sqrt x), ein Float.
367 extern const cl_F sqrt (const cl_F& x);
368
369 // recip(x) liefert (/ x), wo x ein Float ist.
370 extern const cl_F recip (const cl_F& x);
371
372 // (1+ x), wo x ein Float ist.
373 inline const cl_F plus1 (const cl_F& x) // { return x + cl_I(1); }
374 {
375         return x + cl_float(1,x);
376 }
377
378 // (1- x), wo x ein Float ist.
379 inline const cl_F minus1 (const cl_F& x) // { return x + cl_I(-1); }
380 {
381         return x + cl_float(-1,x);
382 }
383
384 // compare(x,y) vergleicht zwei Floats x und y.
385 // Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
386 extern cl_signean compare (const cl_F& x, const cl_F& y);
387
388 // equal_hashcode(x) liefert einen equal-invarianten Hashcode für x.
389 extern uint32 equal_hashcode (const cl_F& x);
390
391 inline bool operator== (const cl_F& x, const cl_F& y)
392         { return compare(x,y)==0; }
393 inline bool operator!= (const cl_F& x, const cl_F& y)
394         { return compare(x,y)!=0; }
395 inline bool operator<= (const cl_F& x, const cl_F& y)
396         { return compare(x,y)<=0; }
397 inline bool operator< (const cl_F& x, const cl_F& y)
398         { return compare(x,y)<0; }
399 inline bool operator>= (const cl_F& x, const cl_F& y)
400         { return compare(x,y)>=0; }
401 inline bool operator> (const cl_F& x, const cl_F& y)
402         { return compare(x,y)>0; }
403
404
405 // ffloor(x) liefert (ffloor x), wo x ein Float ist.
406 extern const cl_F ffloor (const cl_F& x);
407
408 // fceiling(x) liefert (fceiling x), wo x ein Float ist.
409 extern const cl_F fceiling (const cl_F& x);
410
411 // ftruncate(x) liefert (ftruncate x), wo x ein Float ist.
412 extern const cl_F ftruncate (const cl_F& x);
413
414 // fround(x) liefert (fround x), wo x ein Float ist.
415 extern const cl_F fround (const cl_F& x);
416
417
418 // Return type for frounding operators.
419 // x / y  --> (q,r) with x = y*q+r.
420 struct cl_F_fdiv_t {
421         cl_F quotient;
422         cl_F remainder;
423 // Constructor.
424         cl_F_fdiv_t () {}
425         cl_F_fdiv_t (const cl_F& q, const cl_F& r) : quotient(q), remainder(r) {}
426 };
427
428 // ffloor2(x) liefert (ffloor x), wo x ein F ist.
429 extern const cl_F_fdiv_t ffloor2 (const cl_F& x);
430
431 // fceiling2(x) liefert (fceiling x), wo x ein F ist.
432 extern const cl_F_fdiv_t fceiling2 (const cl_F& x);
433
434 // ftruncate2(x) liefert (ftruncate x), wo x ein F ist.
435 extern const cl_F_fdiv_t ftruncate2 (const cl_F& x);
436
437 // fround2(x) liefert (fround x), wo x ein F ist.
438 extern const cl_F_fdiv_t fround2 (const cl_F& x);
439
440
441 // Return type for rounding operators.
442 // x / y  --> (q,r) with x = y*q+r.
443 struct cl_F_div_t {
444         cl_I quotient;
445         cl_F remainder;
446 // Constructor.
447         cl_F_div_t () {}
448         cl_F_div_t (const cl_I& q, const cl_F& r) : quotient(q), remainder(r) {}
449 };
450
451 // floor2(x) liefert (floor x), wo x ein F ist.
452 extern const cl_F_div_t floor2 (const cl_F& x);
453 extern const cl_I floor1 (const cl_F& x);
454
455 // ceiling2(x) liefert (ceiling x), wo x ein F ist.
456 extern const cl_F_div_t ceiling2 (const cl_F& x);
457 extern const cl_I ceiling1 (const cl_F& x);
458
459 // truncate2(x) liefert (truncate x), wo x ein F ist.
460 extern const cl_F_div_t truncate2 (const cl_F& x);
461 extern const cl_I truncate1 (const cl_F& x);
462
463 // round2(x) liefert (round x), wo x ein F ist.
464 extern const cl_F_div_t round2 (const cl_F& x);
465 extern const cl_I round1 (const cl_F& x);
466
467 // floor2(x,y) liefert (floor x y), wo x und y Floats sind.
468 extern const cl_F_div_t floor2 (const cl_F& x, const cl_F& y);
469 inline const cl_I floor1 (const cl_F& x, const cl_F& y) { return floor1(x/y); }
470
471 // ceiling2(x,y) liefert (ceiling x y), wo x und y Floats sind.
472 extern const cl_F_div_t ceiling2 (const cl_F& x, const cl_F& y);
473 inline const cl_I ceiling1 (const cl_F& x, const cl_F& y) { return ceiling1(x/y); }
474
475 // truncate2(x,y) liefert (truncate x y), wo x und y Floats sind.
476 extern const cl_F_div_t truncate2 (const cl_F& x, const cl_F& y);
477 inline const cl_I truncate1 (const cl_F& x, const cl_F& y) { return truncate1(x/y); }
478
479 // round2(x,y) liefert (round x y), wo x und y Floats sind.
480 extern const cl_F_div_t round2 (const cl_F& x, const cl_F& y);
481 inline const cl_I round1 (const cl_F& x, const cl_F& y) { return round1(x/y); }
482
483
484 // Return type for decode_float:
485 struct decoded_float {
486         cl_F mantissa;
487         cl_I exponent;
488         cl_F sign;
489 // Constructor.
490         decoded_float () {}
491         decoded_float (const cl_F& m, const cl_I& e, const cl_F& s) : mantissa(m), exponent(e), sign(s) {}
492 };
493
494 // decode_float(x) liefert zu einem Float x: (decode-float x).
495 // x = 0.0 liefert (0.0, 0, 1.0).
496 // x = (-1)^s * 2^e * m liefert ((-1)^0 * 2^0 * m, e als Integer, (-1)^s).
497 extern const decoded_float decode_float (const cl_F& x);
498
499 // float_exponent(x) liefert zu einem Float x:
500 // den Exponenten von (decode-float x).
501 // x = 0.0 liefert 0.
502 // x = (-1)^s * 2^e * m liefert e.
503 extern sintE float_exponent (const cl_F& x);
504
505 // float_radix(x) liefert (float-radix x), wo x ein Float ist.
506 inline sintL float_radix (const cl_F& x)
507 {
508         (void)x; // unused x
509         return 2;
510 }
511
512 // float_sign(x) liefert (float-sign x), wo x ein Float ist.
513 extern const cl_F float_sign (const cl_F& x);
514
515 // float_sign(x,y) liefert (float-sign x y), wo x und y Floats sind.
516 extern const cl_F float_sign (const cl_F& x, const cl_F& y);
517
518 // float_digits(x) liefert (float-digits x), wo x ein Float ist.
519 // < ergebnis: ein uintC >0
520 extern uintC float_digits (const cl_F& x);
521
522 // float_precision(x) liefert (float-precision x), wo x ein Float ist.
523 // < ergebnis: ein uintC >=0
524 extern uintC float_precision (const cl_F& x);
525
526 // Returns the floating point format of a float.
527 inline float_format_t float_format (const cl_F& x)
528         { return (float_format_t) float_digits(x); }
529
530
531 // integer_decode_float(x) liefert zu einem Float x: (integer-decode-float x).
532 // x = 0.0 liefert (0, 0, 1).
533 // x = (-1)^s * 2^e * m bei Float-Precision p liefert
534 //   (Mantisse 2^p * m als Integer, e-p als Integer, (-1)^s als Fixnum).
535 extern const cl_idecoded_float integer_decode_float (const cl_F& x);
536
537
538 // rational(x) liefert (rational x), wo x ein Float ist.
539 extern const cl_RA rational (const cl_F& x);
540
541
542 // scale_float(x,delta) liefert x*2^delta, wo x ein Float ist.
543 extern const cl_F scale_float (const cl_F& x, sintC delta);
544 extern const cl_F scale_float (const cl_F& x, const cl_I& delta);
545
546
547 // max(x,y) liefert (max x y), wo x und y Floats sind.
548 extern const cl_F max (const cl_F& x, const cl_F& y);
549
550 // min(x,y) liefert (min x y), wo x und y Floats sind.
551 extern const cl_F min (const cl_F& x, const cl_F& y);
552
553 // signum(x) liefert (signum x), wo x ein Float ist.
554 extern const cl_F signum (const cl_F& x);
555
556
557 // Returns the largest (most positive) floating point number in float format f.
558 extern const cl_F most_positive_float (float_format_t f);
559
560 // Returns the smallest (most negative) floating point number in float format f.
561 extern const cl_F most_negative_float (float_format_t f);
562 //CL_REQUIRE(cl_F_mostneg)
563
564 // Returns the least positive floating point number (i.e. > 0 but closest to 0)
565 // in float format f.
566 extern const cl_F least_positive_float (float_format_t f);
567 //CL_REQUIRE(cl_F_leastpos)
568
569 // Returns the least negative floating point number (i.e. < 0 but closest to 0)
570 // in float format f.
571 extern const cl_F least_negative_float (float_format_t f);
572 //CL_REQUIRE(cl_F_leastneg)
573
574 // Returns the smallest floating point number e > 0 such that 1+e != 1.
575 extern const cl_F float_epsilon (float_format_t f);
576 //CL_REQUIRE(cl_F_epspos)
577
578 // Returns the smallest floating point number e > 0 such that 1-e != 1.
579 extern const cl_F float_negative_epsilon (float_format_t f);
580 //CL_REQUIRE(cl_F_epsneg)
581
582
583 // Konversion zu einem C "float".
584 extern float float_approx (const cl_F& x);
585
586 // Konversion zu einem C "double".
587 extern double double_approx (const cl_F& x);
588
589
590 // Transcendental functions
591
592
593 // pi(y) liefert die Zahl pi im selben Float-Format wie y.
594 // > y: ein Float
595 extern const cl_F pi (const cl_F& y);
596
597 // pi(y) liefert die Zahl pi im Float-Format f.
598 // > f: eine Float-Format-Spezifikation
599 extern const cl_F pi (float_format_t f);
600
601 // pi() liefert die Zahl pi im Default-Float-Format.
602 extern const cl_F pi (void);
603
604
605 // sin(x) liefert den Sinus (sin x) eines Float x.
606 extern const cl_F sin (const cl_F& x);
607
608 // cos(x) liefert den Cosinus (cos x) eines Float x.
609 extern const cl_F cos (const cl_F& x);
610
611 // Return type for cos_sin():
612 struct cos_sin_t {
613         cl_R cos;
614         cl_R sin;
615 // Constructor:
616         cos_sin_t () {}
617         cos_sin_t (const cl_R& u, const cl_R& v) : cos (u), sin (v) {}
618 };
619
620 // cos_sin(x) liefert ((cos x),(sin x)), beide Werte.
621 extern const cos_sin_t cos_sin (const cl_F& x);
622
623 // tan(x) liefert den Tangens (tan x) eines Float x.
624 extern const cl_F tan (const cl_F& x);
625
626
627 // exp1(y) liefert die Zahl e = exp(1) im selben Float-Format wie y.
628 // > y: ein Float
629 extern const cl_F exp1 (const cl_F& y);
630
631 // exp1(y) liefert die Zahl e = exp(1) im Float-Format f.
632 // > f: eine Float-Format-Spezifikation
633 extern const cl_F exp1 (float_format_t f);
634
635 // exp1() liefert die Zahl e = exp(1) im Default-Float-Format.
636 extern const cl_F exp1 (void);
637
638
639 // ln(x) liefert zu einem Float x>0 die Zahl ln(x).
640 extern const cl_F ln (const cl_F& x);
641 // Spezialfall: x Long-Float -> Ergebnis Long-Float
642 inline const cl_LF ln (const cl_LF& x) { return The(cl_LF)(ln(The(cl_F)(x))); }
643
644 // exp(x) liefert zu einem Float x die Zahl exp(x).
645 extern const cl_F exp (const cl_F& x);
646
647 // sinh(x) liefert zu einem Float x die Zahl sinh(x).
648 extern const cl_F sinh (const cl_F& x);
649
650 // cosh(x) liefert zu einem Float x die Zahl cosh(x).
651 extern const cl_F cosh (const cl_F& x);
652
653 // Return type for cosh_sinh():
654 struct cosh_sinh_t {
655         cl_R cosh;
656         cl_R sinh;
657 // Constructor:
658         cosh_sinh_t () {}
659         cosh_sinh_t (const cl_R& u, const cl_R& v) : cosh (u), sinh (v) {}
660 };
661
662 // cosh_sinh(x) liefert ((cosh x),(sinh x)), beide Werte.
663 extern const cosh_sinh_t cosh_sinh (const cl_F& x);
664
665 // tanh(x) liefert zu einem Float x die Zahl tanh(x).
666 extern const cl_F tanh (const cl_F& x);
667
668
669 // eulerconst(y) liefert die Eulersche Konstante
670 // im selben Float-Format wie y.
671 // > y: ein Float
672 extern const cl_F eulerconst (const cl_F& y);
673
674 // eulerconst(y) liefert die Eulersche Konstante im Float-Format f.
675 // > f: eine Float-Format-Spezifikation
676 extern const cl_F eulerconst (float_format_t f);
677
678 // eulerconst() liefert die Eulersche Konstante im Default-Float-Format.
679 extern const cl_F eulerconst (void);
680
681 // catalanconst(y) liefert die Catalansche Konstante
682 // im selben Float-Format wie y.
683 // > y: ein Float
684 extern const cl_F catalanconst (const cl_F& y);
685
686 // catalanconst(y) liefert die Catalansche Konstante im Float-Format f.
687 // > f: eine Float-Format-Spezifikation
688 extern const cl_F catalanconst (float_format_t f);
689
690 // catalanconst() liefert die Catalansche Konstante im Default-Float-Format.
691 extern const cl_F catalanconst (void);
692
693 // zeta(s) returns the Riemann zeta function at s>1.
694 extern const cl_F zeta (int s, const cl_F& y);
695 extern const cl_F zeta (int s, float_format_t f);
696 extern const cl_F zeta (int s);
697
698
699 // random_F(randomstate,n) liefert zu einem Float n>0 ein zufälliges
700 // Float x mit 0 <= x < n.
701 // > randomstate: ein Random-State, wird verändert
702 extern const cl_F random_F (random_state& randomstate, const cl_F& n);
703
704 inline const cl_F random_F (const cl_F& n)
705         { return random_F(default_random_state,n); }
706
707
708 // This could be optimized to use in-place operations.
709 inline cl_F& operator+= (cl_F& x, const cl_F& y) { return x = x + y; }
710 inline cl_F& operator+= (cl_F& x, const float y) { return x = x + y; }
711 inline cl_F& operator+= (cl_F& x, const double y) { return x = x + y; }
712 inline cl_F& operator++ /* prefix */ (cl_F& x) { return x = plus1(x); }
713 inline void operator++ /* postfix */ (cl_F& x, int dummy) { (void)dummy; x = plus1(x); }
714 inline cl_F& operator-= (cl_F& x, const cl_F& y) { return x = x - y; }
715 inline cl_F& operator-= (cl_F& x, const float y) { return x = x - y; }
716 inline cl_F& operator-= (cl_F& x, const double y) { return x = x - y; }
717 inline cl_F& operator-- /* prefix */ (cl_F& x) { return x = minus1(x); }
718 inline void operator-- /* postfix */ (cl_F& x, int dummy) { (void)dummy; x = minus1(x); }
719 inline cl_F& operator*= (cl_F& x, const cl_F& y) { return x = x * y; }
720 inline cl_F& operator*= (cl_F& x, const float y) { return x = x * y; }
721 inline cl_F& operator*= (cl_F& x, const double y) { return x = x * y; }
722 inline cl_F& operator/= (cl_F& x, const cl_F& y) { return x = x / y; }
723 inline cl_F& operator/= (cl_F& x, const float y) { return x = x / y; }
724 inline cl_F& operator/= (cl_F& x, const double y) { return x = x / y; }
725
726 // Thrown when a floating-point exception occurs.
727 class floating_point_exception : public runtime_exception {
728 public:
729         explicit floating_point_exception(const std::string & what)
730                 : runtime_exception(what) {}
731 };
732
733 // Thrown when NaN occurs.
734 class floating_point_nan_exception : public floating_point_exception {
735 public:
736         floating_point_nan_exception();
737 };
738
739 // Thrown when overflow occurs.
740 class floating_point_overflow_exception : public floating_point_exception {
741 public:
742         floating_point_overflow_exception();
743 };
744
745 // Thrown when underflow occurs.
746 class floating_point_underflow_exception : public floating_point_exception {
747 public:
748         floating_point_underflow_exception();
749 };
750
751
752
753
754 // If this is true, floating point underflow returns zero instead of throwing an exception.
755 extern bool cl_inhibit_floating_point_underflow;
756
757 }  // namespace cln
758
759 #endif /* _CL_FLOAT_H */