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