1 // Public short float operations.
6 #include "cln/number.h"
7 #include "cln/sfloat_class.h"
8 #include "cln/integer_class.h"
13 CL_DEFINE_AS_CONVERSION(cl_SF)
16 // Liefert zu einem Short-Float x : (- x), ein SF.
17 extern const cl_SF operator- (const cl_SF& x);
19 // compare(x,y) vergleicht zwei Short-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_SF& x, const cl_SF& y);
23 // equal_hashcode(x) liefert einen equal-invarianten Hashcode für x.
24 extern uint32 equal_hashcode (const cl_SF& x);
26 inline bool operator== (const cl_SF& x, const cl_SF& y)
27 { return compare(x,y)==0; }
28 inline bool operator!= (const cl_SF& x, const cl_SF& y)
29 { return compare(x,y)!=0; }
30 inline bool operator<= (const cl_SF& x, const cl_SF& y)
31 { return compare(x,y)<=0; }
32 inline bool operator< (const cl_SF& x, const cl_SF& y)
33 { return compare(x,y)<0; }
34 inline bool operator>= (const cl_SF& x, const cl_SF& y)
35 { return compare(x,y)>=0; }
36 inline bool operator> (const cl_SF& x, const cl_SF& y)
37 { return compare(x,y)>0; }
39 // minusp(x) == (< x 0)
40 extern cl_boolean minusp (const cl_SF& x);
42 // zerop(x) stellt fest, ob ein Short-Float x = 0.0 ist.
43 extern cl_boolean zerop (const cl_SF& x);
45 // plusp(x) == (> x 0)
46 extern cl_boolean plusp (const cl_SF& x);
48 // Liefert zu zwei Short-Float x und y : (+ x y), ein SF.
49 extern const cl_SF operator+ (const cl_SF& x, const cl_SF& y);
51 // Liefert zu zwei Short-Float x und y : (- x y), ein SF.
52 extern const cl_SF operator- (const cl_SF& x, const cl_SF& y);
54 // Liefert zu zwei Short-Float x und y : (* x y), ein SF.
55 extern const cl_SF operator* (const cl_SF& x, const cl_SF& y);
57 // Liefert zu einem Short-Float x : (* x x), ein SF.
58 inline const cl_SF square (const cl_SF& x) { return x*x; }
60 // Liefert zu zwei Short-Float x und y : (/ x y), ein SF.
61 extern const cl_SF operator/ (const cl_SF& x, const cl_SF& y);
63 // Liefert zu einem Short-Float x>=0 : (sqrt x), ein SF.
64 extern const cl_SF sqrt (const cl_SF& x);
66 // recip(x) liefert (/ x), wo x ein Short-Float ist.
67 extern const cl_SF recip (const cl_SF& x);
69 // abs(x) liefert (abs x), wo x ein Short-Float ist.
70 extern const cl_SF abs (const cl_SF& x);
73 // (1+ x), wo x ein Short-Float ist.
74 inline const cl_SF plus1 (const cl_SF& x)
76 extern const cl_SF cl_I_to_SF (const cl_I&);
77 return x + cl_I_to_SF(cl_I(1));
80 // (1- x), wo x ein Short-Float ist.
81 inline const cl_SF minus1 (const cl_SF& x)
83 extern const cl_SF cl_I_to_SF (const cl_I&);
84 return x + cl_I_to_SF(cl_I(-1));
88 // ffloor(x) liefert (ffloor x), wo x ein SF ist.
89 extern const cl_SF ffloor (const cl_SF& x);
91 // fceiling(x) liefert (fceiling x), wo x ein SF ist.
92 extern const cl_SF fceiling (const cl_SF& x);
94 // ftruncate(x) liefert (ftruncate x), wo x ein SF ist.
95 extern const cl_SF ftruncate (const cl_SF& x);
97 // fround(x) liefert (fround x), wo x ein SF ist.
98 extern const cl_SF fround (const cl_SF& x);
101 // Return type for frounding operators.
102 // x / y --> (q,r) with x = y*q+r.
103 struct cl_SF_fdiv_t {
108 cl_SF_fdiv_t (const cl_SF& q, const cl_SF& r) : quotient(q), remainder(r) {}
111 // ffloor2(x) liefert (ffloor x), wo x ein SF ist.
112 inline const cl_SF_fdiv_t ffloor2 (const cl_SF& x)
113 { cl_SF q = ffloor(x); return cl_SF_fdiv_t(q,x-q); }
115 // fceiling2(x) liefert (fceiling x), wo x ein SF ist.
116 inline const cl_SF_fdiv_t fceiling2 (const cl_SF& x)
117 { cl_SF q = fceiling(x); return cl_SF_fdiv_t(q,x-q); }
119 // ftruncate2(x) liefert (ftruncate x), wo x ein SF ist.
120 inline const cl_SF_fdiv_t ftruncate2 (const cl_SF& x)
121 { cl_SF q = ftruncate(x); return cl_SF_fdiv_t(q,x-q); }
123 // fround2(x) liefert (fround x), wo x ein SF ist.
124 inline const cl_SF_fdiv_t fround2 (const cl_SF& x)
125 { cl_SF q = fround(x); return cl_SF_fdiv_t(q,x-q); }
128 // Return type for rounding operators.
129 // x / y --> (q,r) with x = y*q+r.
135 cl_SF_div_t (const cl_I& q, const cl_SF& r) : quotient(q), remainder(r) {}
138 // floor2(x) liefert (floor x), wo x ein SF ist.
139 inline const cl_SF_div_t floor2 (const cl_SF& x)
141 extern const cl_I cl_SF_to_I (const cl_SF& x);
143 return cl_SF_div_t(cl_SF_to_I(q),x-q);
145 inline const cl_I floor1 (const cl_SF& x)
147 extern const cl_I cl_SF_to_I (const cl_SF& x);
148 return cl_SF_to_I(ffloor(x));
151 // ceiling2(x) liefert (ceiling x), wo x ein SF ist.
152 inline const cl_SF_div_t ceiling2 (const cl_SF& x)
154 extern const cl_I cl_SF_to_I (const cl_SF& x);
155 cl_SF q = fceiling(x);
156 return cl_SF_div_t(cl_SF_to_I(q),x-q);
158 inline const cl_I ceiling1 (const cl_SF& x)
160 extern const cl_I cl_SF_to_I (const cl_SF& x);
161 return cl_SF_to_I(fceiling(x));
164 // truncate2(x) liefert (truncate x), wo x ein SF ist.
165 inline const cl_SF_div_t truncate2 (const cl_SF& x)
167 extern const cl_I cl_SF_to_I (const cl_SF& x);
168 cl_SF q = ftruncate(x);
169 return cl_SF_div_t(cl_SF_to_I(q),x-q);
171 inline const cl_I truncate1 (const cl_SF& x)
173 extern const cl_I cl_SF_to_I (const cl_SF& x);
174 return cl_SF_to_I(ftruncate(x));
177 // round2(x) liefert (round x), wo x ein SF ist.
178 inline const cl_SF_div_t round2 (const cl_SF& x)
180 extern const cl_I cl_SF_to_I (const cl_SF& x);
182 return cl_SF_div_t(cl_SF_to_I(q),x-q);
184 inline const cl_I round1 (const cl_SF& x)
186 extern const cl_I cl_SF_to_I (const cl_SF& x);
187 return cl_SF_to_I(fround(x));
190 // floor2(x,y) liefert (floor x y).
191 extern const cl_SF_div_t floor2 (const cl_SF& x, const cl_SF& y);
192 inline const cl_I floor1 (const cl_SF& x, const cl_SF& y) { return floor1(x/y); }
194 // ceiling2(x,y) liefert (ceiling x y).
195 extern const cl_SF_div_t ceiling2 (const cl_SF& x, const cl_SF& y);
196 inline const cl_I ceiling1 (const cl_SF& x, const cl_SF& y) { return ceiling1(x/y); }
198 // truncate2(x,y) liefert (truncate x y).
199 extern const cl_SF_div_t truncate2 (const cl_SF& x, const cl_SF& y);
200 inline const cl_I truncate1 (const cl_SF& x, const cl_SF& y) { return truncate1(x/y); }
202 // round2(x,y) liefert (round x y).
203 extern const cl_SF_div_t round2 (const cl_SF& x, const cl_SF& y);
204 inline const cl_I round1 (const cl_SF& x, const cl_SF& y) { return round1(x/y); }
207 // Return type for decode_float:
208 struct decoded_sfloat {
214 decoded_sfloat (const cl_SF& m, const cl_I& e, const cl_SF& s) : mantissa(m), exponent(e), sign(s) {}
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_sfloat decode_float (const cl_SF& x);
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_SF& x);
228 // float_radix(x) liefert (float-radix x), wo x ein Float ist.
229 inline sintL float_radix (const cl_SF& x)
235 // float_sign(x) liefert (float-sign x), wo x ein Float ist.
236 extern const cl_SF float_sign (const cl_SF& x);
238 // float_digits(x) liefert (float-digits x), wo x ein Float ist.
239 // < ergebnis: ein uintC >0
240 extern uintC float_digits (const cl_SF& x);
242 // float_precision(x) liefert (float-precision x), wo x ein Float ist.
243 // < ergebnis: ein uintC >=0
244 extern uintC float_precision (const cl_SF& x);
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_SF& x);
254 // scale_float(x,delta) liefert x*2^delta, wo x ein SF ist.
255 extern const cl_SF scale_float (const cl_SF& x, sintC delta);
256 extern const cl_SF scale_float (const cl_SF& x, const cl_I& delta);
259 // max(x,y) liefert (max x y), wo x und y Floats sind.
260 extern const cl_SF max (const cl_SF& x, const cl_SF& y);
262 // min(x,y) liefert (min x y), wo x und y Floats sind.
263 extern const cl_SF min (const cl_SF& x, const cl_SF& y);
265 // signum(x) liefert (signum x), wo x ein Float ist.
266 extern const cl_SF signum (const cl_SF& x);
269 // Konversion zu einem C "float".
270 extern float float_approx (const cl_SF& x);
272 // Konversion zu einem C "double".
273 extern double double_approx (const cl_SF& x);
276 #ifdef WANT_OBFUSCATING_OPERATORS
277 // This could be optimized to use in-place operations.
278 inline cl_SF& operator+= (cl_SF& x, const cl_SF& y) { return x = x + y; }
279 inline cl_SF& operator++ /* prefix */ (cl_SF& x) { return x = plus1(x); }
280 inline void operator++ /* postfix */ (cl_SF& x, int dummy) { (void)dummy; x = plus1(x); }
281 inline cl_SF& operator-= (cl_SF& x, const cl_SF& y) { return x = x - y; }
282 inline cl_SF& operator-- /* prefix */ (cl_SF& x) { return x = minus1(x); }
283 inline void operator-- /* postfix */ (cl_SF& x, int dummy) { (void)dummy; x = minus1(x); }
284 inline cl_SF& operator*= (cl_SF& x, const cl_SF& y) { return x = x * y; }
285 inline cl_SF& operator/= (cl_SF& x, const cl_SF& y) { return x = x / y; }
289 // Runtime typing support.
290 extern cl_class cl_class_sfloat;
291 CL_FORCE_LINK(cl_SF_classes_dummy, cl_class_sfloat)
294 // Debugging support.
296 extern int cl_SF_debug_module;
297 CL_FORCE_LINK(cl_SF_debug_dummy, cl_SF_debug_module)
302 #endif /* _CL_SFLOAT_H */