1 // Public double float operations.
7 #include "cl_dfloat_class.h"
8 #include "cl_integer_class.h"
12 CL_DEFINE_AS_CONVERSION(cl_DF)
15 // Liefert zu einem Double-Float x : (- x), ein DF.
16 extern const cl_DF operator- (const cl_DF& x);
18 // cl_compare(x,y) vergleicht zwei Double-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_DF& x, const cl_DF& y);
22 // cl_equal_hashcode(x) liefert einen cl_equal-invarianten Hashcode für x.
23 extern uint32 cl_equal_hashcode (const cl_DF& x);
25 inline bool operator== (const cl_DF& x, const cl_DF& y)
26 { return cl_compare(x,y)==0; }
27 inline bool operator!= (const cl_DF& x, const cl_DF& y)
28 { return cl_compare(x,y)!=0; }
29 inline bool operator<= (const cl_DF& x, const cl_DF& y)
30 { return cl_compare(x,y)<=0; }
31 inline bool operator< (const cl_DF& x, const cl_DF& y)
32 { return cl_compare(x,y)<0; }
33 inline bool operator>= (const cl_DF& x, const cl_DF& y)
34 { return cl_compare(x,y)>=0; }
35 inline bool operator> (const cl_DF& x, const cl_DF& y)
36 { return cl_compare(x,y)>0; }
38 // minusp(x) == (< x 0)
39 extern cl_boolean minusp (const cl_DF& x);
41 // zerop(x) stellt fest, ob ein Double-Float x = 0.0 ist.
42 extern cl_boolean zerop (const cl_DF& x);
44 // plusp(x) == (> x 0)
45 extern cl_boolean plusp (const cl_DF& x);
47 // Liefert zu zwei Double-Float x und y : (+ x y), ein DF.
48 extern const cl_DF operator+ (const cl_DF& x, const cl_DF& y);
50 // Liefert zu zwei Double-Float x und y : (- x y), ein DF.
51 extern const cl_DF operator- (const cl_DF& x, const cl_DF& y);
53 // Liefert zu zwei Double-Float x und y : (* x y), ein DF.
54 extern const cl_DF operator* (const cl_DF& x, const cl_DF& y);
56 // Liefert zu einem Double-Float x : (* x x), ein DF.
57 inline const cl_DF square (const cl_DF& x) { return x*x; }
59 // Liefert zu zwei Double-Float x und y : (/ x y), ein DF.
60 extern const cl_DF operator/ (const cl_DF& x, const cl_DF& y);
62 // Liefert zu einem Double-Float x>=0 : (sqrt x), ein DF.
63 extern const cl_DF sqrt (const cl_DF& x);
65 // recip(x) liefert (/ x), wo x ein Double-Float ist.
66 extern const cl_DF recip (const cl_DF& x);
68 // abs(x) liefert (abs x), wo x ein Double-Float ist.
69 extern const cl_DF abs (const cl_DF& x);
72 // (1+ x), wo x ein Double-Float ist.
73 inline const cl_DF plus1 (const cl_DF& x)
75 extern const cl_DF cl_I_to_DF (const cl_I&);
76 return x + cl_I_to_DF(cl_I(1));
79 // (1- x), wo x ein Double-Float ist.
80 inline const cl_DF minus1 (const cl_DF& x)
82 extern const cl_DF cl_I_to_DF (const cl_I&);
83 return x + cl_I_to_DF(cl_I(-1));
87 // ffloor(x) liefert (ffloor x), wo x ein DF ist.
88 extern const cl_DF ffloor (const cl_DF& x);
90 // fceiling(x) liefert (fceiling x), wo x ein DF ist.
91 extern const cl_DF fceiling (const cl_DF& x);
93 // ftruncate(x) liefert (ftruncate x), wo x ein DF ist.
94 extern const cl_DF ftruncate (const cl_DF& x);
96 // fround(x) liefert (fround x), wo x ein DF ist.
97 extern const cl_DF fround (const cl_DF& x);
100 // Return type for frounding operators.
101 // x / y --> (q,r) with x = y*q+r.
102 struct cl_DF_fdiv_t {
107 cl_DF_fdiv_t (const cl_DF& q, const cl_DF& r) : quotient(q), remainder(r) {}
110 // ffloor2(x) liefert (ffloor x), wo x ein DF ist.
111 inline const cl_DF_fdiv_t ffloor2 (const cl_DF& x)
112 { cl_DF q = ffloor(x); return cl_DF_fdiv_t(q,x-q); }
114 // fceiling2(x) liefert (fceiling x), wo x ein DF ist.
115 inline const cl_DF_fdiv_t fceiling2 (const cl_DF& x)
116 { cl_DF q = fceiling(x); return cl_DF_fdiv_t(q,x-q); }
118 // ftruncate2(x) liefert (ftruncate x), wo x ein DF ist.
119 inline const cl_DF_fdiv_t ftruncate2 (const cl_DF& x)
120 { cl_DF q = ftruncate(x); return cl_DF_fdiv_t(q,x-q); }
122 // fround2(x) liefert (fround x), wo x ein DF ist.
123 inline const cl_DF_fdiv_t fround2 (const cl_DF& x)
124 { cl_DF q = fround(x); return cl_DF_fdiv_t(q,x-q); }
127 // Return type for rounding operators.
128 // x / y --> (q,r) with x = y*q+r.
134 cl_DF_div_t (const cl_I& q, const cl_DF& r) : quotient(q), remainder(r) {}
137 // floor2(x) liefert (floor x), wo x ein DF ist.
138 inline const cl_DF_div_t floor2 (const cl_DF& x)
140 extern const cl_I cl_DF_to_I (const cl_DF& x);
142 return cl_DF_div_t(cl_DF_to_I(q),x-q);
144 inline const cl_I floor1 (const cl_DF& x)
146 extern const cl_I cl_DF_to_I (const cl_DF& x);
147 return cl_DF_to_I(ffloor(x));
150 // ceiling2(x) liefert (ceiling x), wo x ein DF ist.
151 inline const cl_DF_div_t ceiling2 (const cl_DF& x)
153 extern const cl_I cl_DF_to_I (const cl_DF& x);
154 cl_DF q = fceiling(x);
155 return cl_DF_div_t(cl_DF_to_I(q),x-q);
157 inline const cl_I ceiling1 (const cl_DF& x)
159 extern const cl_I cl_DF_to_I (const cl_DF& x);
160 return cl_DF_to_I(fceiling(x));
163 // truncate2(x) liefert (truncate x), wo x ein DF ist.
164 inline const cl_DF_div_t truncate2 (const cl_DF& x)
166 extern const cl_I cl_DF_to_I (const cl_DF& x);
167 cl_DF q = ftruncate(x);
168 return cl_DF_div_t(cl_DF_to_I(q),x-q);
170 inline const cl_I truncate1 (const cl_DF& x)
172 extern const cl_I cl_DF_to_I (const cl_DF& x);
173 return cl_DF_to_I(ftruncate(x));
176 // round2(x) liefert (round x), wo x ein DF ist.
177 inline const cl_DF_div_t round2 (const cl_DF& x)
179 extern const cl_I cl_DF_to_I (const cl_DF& x);
181 return cl_DF_div_t(cl_DF_to_I(q),x-q);
183 inline const cl_I round1 (const cl_DF& x)
185 extern const cl_I cl_DF_to_I (const cl_DF& x);
186 return cl_DF_to_I(fround(x));
189 // floor2(x,y) liefert (floor x y).
190 extern const cl_DF_div_t floor2 (const cl_DF& x, const cl_DF& y);
191 inline const cl_I floor1 (const cl_DF& x, const cl_DF& y) { return floor1(x/y); }
193 // ceiling2(x,y) liefert (ceiling x y).
194 extern const cl_DF_div_t ceiling2 (const cl_DF& x, const cl_DF& y);
195 inline const cl_I ceiling1 (const cl_DF& x, const cl_DF& y) { return ceiling1(x/y); }
197 // truncate2(x,y) liefert (truncate x y).
198 extern const cl_DF_div_t truncate2 (const cl_DF& x, const cl_DF& y);
199 inline const cl_I truncate1 (const cl_DF& x, const cl_DF& y) { return truncate1(x/y); }
201 // round2(x,y) liefert (round x y).
202 extern const cl_DF_div_t round2 (const cl_DF& x, const cl_DF& y);
203 inline const cl_I round1 (const cl_DF& x, const cl_DF& y) { return round1(x/y); }
206 // Return type for decode_float:
207 struct cl_decoded_dfloat {
212 cl_decoded_dfloat () {}
213 cl_decoded_dfloat (const cl_DF& m, const cl_I& e, const cl_DF& s) : mantissa(m), exponent(e), sign(s) {}
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_dfloat decode_float (const cl_DF& x);
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_DF& x);
227 // float_radix(x) liefert (float-radix x), wo x ein Float ist.
228 inline sintL float_radix (const cl_DF& x)
234 // float_sign(x) liefert (float-sign x), wo x ein Float ist.
235 extern const cl_DF float_sign (const cl_DF& x);
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_DF& x);
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_DF& x);
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_DF& x);
253 // scale_float(x,delta) liefert x*2^delta, wo x ein DF ist.
254 extern const cl_DF scale_float (const cl_DF& x, sintL delta);
255 extern const cl_DF scale_float (const cl_DF& x, const cl_I& delta);
258 // max(x,y) liefert (max x y), wo x und y Floats sind.
259 extern const cl_DF max (const cl_DF& x, const cl_DF& y);
261 // min(x,y) liefert (min x y), wo x und y Floats sind.
262 extern const cl_DF min (const cl_DF& x, const cl_DF& y);
264 // signum(x) liefert (signum x), wo x ein Float ist.
265 extern const cl_DF signum (const cl_DF& x);
268 // Konversion zu einem C "float".
269 extern float cl_float_approx (const cl_DF& x);
271 // Konversion zu einem C "double".
272 extern double cl_double_approx (const cl_DF& x);
275 #ifdef WANT_OBFUSCATING_OPERATORS
276 // This could be optimized to use in-place operations.
277 inline cl_DF& operator+= (cl_DF& x, const cl_DF& y) { return x = x + y; }
278 inline cl_DF& operator++ /* prefix */ (cl_DF& x) { return x = plus1(x); }
279 inline void operator++ /* postfix */ (cl_DF& x, int dummy) { (void)dummy; x = plus1(x); }
280 inline cl_DF& operator-= (cl_DF& x, const cl_DF& y) { return x = x - y; }
281 inline cl_DF& operator-- /* prefix */ (cl_DF& x) { return x = minus1(x); }
282 inline void operator-- /* postfix */ (cl_DF& x, int dummy) { (void)dummy; x = minus1(x); }
283 inline cl_DF& operator*= (cl_DF& x, const cl_DF& y) { return x = x * y; }
284 inline cl_DF& operator/= (cl_DF& x, const cl_DF& y) { return x = x / y; }
292 // Runtime typing support.
293 extern cl_class cl_class_dfloat;
296 // Debugging support.
298 extern int cl_DF_debug_module;
299 static void* const cl_DF_debug_dummy[] = { &cl_DF_debug_dummy,
305 #endif /* _CL_DFLOAT_H */