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