1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338
|
// Public float operations.
#ifndef _CL_FLOAT_H
#define _CL_FLOAT_H
#include "cl_number.h"
#include "cl_floatformat.h"
// Liefert (- x), wo x ein Float ist.
extern cl_F operator- (const cl_F& x);
// Liefert (+ x y), wo x und y Floats sind.
extern cl_F operator+ (const cl_F& x, const cl_F& y);
// Liefert (- x y), wo x und y Floats sind.
extern cl_F operator- (const cl_F& x, const cl_F& y);
// Liefert (* x y), wo x und y Floats sind.
extern cl_F operator* (const cl_F& x, const cl_F& y);
// Liefert (* x x), wo x ein Float ist.
extern cl_F square (const cl_F& x);
// Liefert (/ x y), wo x und y Floats sind.
extern cl_F operator/ (const cl_F& x, const cl_F& y);
// Liefert (abs x), wo x ein Float ist.
extern cl_F abs (const cl_F& x);
// Liefert zu einem Float x>=0 : (sqrt x), ein Float.
extern cl_F sqrt (const cl_F& x);
// recip(x) liefert (/ x), wo x ein Float ist.
extern cl_F recip (const cl_F& x);
// (1+ x), wo x ein Float ist.
inline cl_F plus1 (const cl_F& x) // { return x + cl_I(1); }
{
extern cl_F cl_float (const cl_R&, const cl_F&);
return x + cl_float(cl_I(1),x);
}
// (1- x), wo x ein Float ist.
inline cl_F minus1 (const cl_F& x) // { return x + cl_I(-1); }
{
extern cl_F cl_float (const cl_R&, const cl_F&);
return x + cl_float(cl_I(-1),x);
}
// zerop(x) testet, ob (= x 0).
extern cl_boolean zerop (const cl_F& x);
// minusp(x) testet, ob (< x 0).
extern cl_boolean minusp (const cl_F& x);
// cl_compare(x,y) vergleicht zwei Floats x und y.
// Ergebnis: 0 falls x=y, +1 falls x>y, -1 falls x<y.
extern cl_signean cl_compare (const cl_F& x, const cl_F& y);
inline bool operator== (const cl_F& x, const cl_F& y)
{ return cl_compare(x,y)==0; }
inline bool operator!= (const cl_F& x, const cl_F& y)
{ return cl_compare(x,y)!=0; }
inline bool operator<= (const cl_F& x, const cl_F& y)
{ return cl_compare(x,y)<=0; }
inline bool operator< (const cl_F& x, const cl_F& y)
{ return cl_compare(x,y)<0; }
inline bool operator>= (const cl_F& x, const cl_F& y)
{ return cl_compare(x,y)>=0; }
inline bool operator> (const cl_F& x, const cl_F& y)
{ return cl_compare(x,y)>0; }
// ffloor(x) liefert (ffloor x), wo x ein Float ist.
extern cl_F ffloor (const cl_F& x);
// fceiling(x) liefert (fceiling x), wo x ein Float ist.
extern cl_F fceiling (const cl_F& x);
// ftruncate(x) liefert (ftruncate x), wo x ein Float ist.
extern cl_F ftruncate (const cl_F& x);
// fround(x) liefert (fround x), wo x ein Float ist.
extern cl_F fround (const cl_F& x);
// Return type for frounding operators.
// x / y --> (q,r) with x = y*q+r.
struct cl_F_fdiv_t {
cl_F quotient;
cl_F remainder;
// Constructor.
cl_F_fdiv_t () {}
cl_F_fdiv_t (const cl_F& q, const cl_F& r) : quotient(q), remainder(r) {}
};
// ffloor2(x) liefert (ffloor x), wo x ein F ist.
extern cl_F_fdiv_t ffloor2 (const cl_F& x);
// fceiling2(x) liefert (fceiling x), wo x ein F ist.
extern cl_F_fdiv_t fceiling2 (const cl_F& x);
// ftruncate2(x) liefert (ftruncate x), wo x ein F ist.
extern cl_F_fdiv_t ftruncate2 (const cl_F& x);
// fround2(x) liefert (fround x), wo x ein F ist.
extern cl_F_fdiv_t fround2 (const cl_F& x);
// Return type for rounding operators.
// x / y --> (q,r) with x = y*q+r.
struct cl_F_div_t {
cl_I quotient;
cl_F remainder;
// Constructor.
cl_F_div_t () {}
cl_F_div_t (const cl_I& q, const cl_F& r) : quotient(q), remainder(r) {}
};
// floor2(x) liefert (floor x), wo x ein F ist.
extern cl_F_div_t floor2 (const cl_F& x);
extern cl_I floor1 (const cl_F& x);
// ceiling2(x) liefert (ceiling x), wo x ein F ist.
extern cl_F_div_t ceiling2 (const cl_F& x);
extern cl_I ceiling1 (const cl_F& x);
// truncate2(x) liefert (truncate x), wo x ein F ist.
extern cl_F_div_t truncate2 (const cl_F& x);
extern cl_I truncate1 (const cl_F& x);
// round2(x) liefert (round x), wo x ein F ist.
extern cl_F_div_t round2 (const cl_F& x);
extern cl_I round1 (const cl_F& x);
// floor2(x,y) liefert (floor x y), wo x und y Floats sind.
extern cl_F_div_t floor2 (const cl_F& x, const cl_F& y);
inline cl_I floor1 (const cl_F& x, const cl_F& y) { return floor1(x/y); }
// ceiling2(x,y) liefert (ceiling x y), wo x und y Floats sind.
extern cl_F_div_t ceiling2 (const cl_F& x, const cl_F& y);
inline cl_I ceiling1 (const cl_F& x, const cl_F& y) { return ceiling1(x/y); }
// truncate2(x,y) liefert (truncate x y), wo x und y Floats sind.
extern cl_F_div_t truncate2 (const cl_F& x, const cl_F& y);
inline cl_I truncate1 (const cl_F& x, const cl_F& y) { return truncate1(x/y); }
// round2(x,y) liefert (round x y), wo x und y Floats sind.
extern cl_F_div_t round2 (const cl_F& x, const cl_F& y);
inline cl_I round1 (const cl_F& x, const cl_F& y) { return round1(x/y); }
// The default float format used when converting rational numbers to floats.
extern cl_float_format_t cl_default_float_format;
// Returns the smallest float format which guarantees at least n decimal digits
// in the mantissa (after the decimal point).
extern cl_float_format_t cl_float_format (uintL n);
// cl_float(x,y) wandelt ein Float x in das Float-Format des Floats y um
// und rundet dabei ntigenfalls.
// > x,y: Floats
// < ergebnis: (float x y)
extern cl_F cl_float (const cl_F& x, const cl_F& y);
// cl_float(x,f) wandelt ein Float x in das Float-Format f um
// und rundet dabei ntigenfalls.
// > x: ein Float
// > f: eine Float-Format-Spezifikation
// < ergebnis: (float x f)
extern cl_F cl_float (const cl_F& x, cl_float_format_t f);
// cl_float(x,y) wandelt ein Integer x in das Float-Format des Floats y um
// und rundet dabei ntigenfalls.
// > x: ein Integer
// > y: ein Float
// < ergebnis: (float x y)
extern cl_F cl_float (const cl_I& x, const cl_F& y);
// cl_float(x,y) wandelt ein Integer x in das Float-Format f um
// und rundet dabei ntigenfalls.
// > x: ein Integer
// > f: eine Float-Format-Spezifikation
// < ergebnis: (float x f)
extern cl_F cl_float (const cl_I& x, cl_float_format_t f);
// cl_float(x,y) wandelt eine rationale Zahl x in das Float-Format des
// Floats y um und rundet dabei ntigenfalls.
// > x: eine rationale Zahl
// > y: ein Float
// < ergebnis: (float x y)
extern cl_F cl_float (const cl_RA& x, const cl_F& y);
// cl_float(x,y) wandelt eine rationale Zahl x in das Float-Format f um
// und rundet dabei ntigenfalls.
// > x: eine rationale Zahl
// > f: eine Float-Format-Spezifikation
// < ergebnis: (float x f)
extern cl_F cl_float (const cl_RA& x, cl_float_format_t f);
// The C++ compilers are not clever enough to guess this:
inline cl_F cl_float (int x, const cl_F& y)
{ return cl_float(cl_I(x),y); }
inline cl_F cl_float (unsigned int x, const cl_F& y)
{ return cl_float(cl_I(x),y); }
inline cl_F cl_float (int x, cl_float_format_t y)
{ return cl_float(cl_I(x),y); }
inline cl_F cl_float (unsigned int x, cl_float_format_t y)
{ return cl_float(cl_I(x),y); }
// The C++ compilers could hardly guess the following:
inline cl_F cl_float (float x, const cl_F& y)
{ return cl_float(cl_FF(x),y); }
inline cl_F cl_float (double x, const cl_F& y)
{ return cl_float(cl_DF(x),y); }
inline cl_F cl_float (float x, cl_float_format_t y)
{ return cl_float(cl_FF(x),y); }
inline cl_F cl_float (double x, cl_float_format_t y)
{ return cl_float(cl_DF(x),y); }
// Return type for decode_float:
struct cl_decoded_float {
cl_F mantissa;
cl_I exponent;
cl_F sign;
// Constructor.
cl_decoded_float () {}
cl_decoded_float (const cl_F& m, const cl_I& e, const cl_F& s) : mantissa(m), exponent(e), sign(s) {}
};
// decode_float(x) liefert zu einem Float x: (decode-float x).
// x = 0.0 liefert (0.0, 0, 1.0).
// x = (-1)^s * 2^e * m liefert ((-1)^0 * 2^0 * m, e als Integer, (-1)^s).
extern cl_decoded_float decode_float (const cl_F& x);
// float_exponent(x) liefert zu einem Float x:
// den Exponenten von (decode-float x).
// x = 0.0 liefert 0.
// x = (-1)^s * 2^e * m liefert e.
extern sintL float_exponent (const cl_F& x);
// float_radix(x) liefert (float-radix x), wo x ein Float ist.
inline sintL float_radix (const cl_F& x)
{
(void)x; // unused x
return 2;
}
// float_sign(x) liefert (float-sign x), wo x ein Float ist.
extern cl_F float_sign (const cl_F& x);
// float_sign(x,y) liefert (float-sign x y), wo x und y Floats sind.
extern cl_F float_sign (const cl_F& x, const cl_F& y);
// float_digits(x) liefert (float-digits x), wo x ein Float ist.
// < ergebnis: ein uintL >0
extern uintL float_digits (const cl_F& x);
// float_precision(x) liefert (float-precision x), wo x ein Float ist.
// < ergebnis: ein uintL >=0
extern uintL float_precision (const cl_F& x);
// Returns the floating point format of a float.
inline cl_float_format_t cl_float_format (const cl_F& x)
{ return (cl_float_format_t) float_digits(x); }
// integer_decode_float(x) liefert zu einem Float x: (integer-decode-float x).
// x = 0.0 liefert (0, 0, 1).
// x = (-1)^s * 2^e * m bei Float-Precision p liefert
// (Mantisse 2^p * m als Integer, e-p als Integer, (-1)^s als Fixnum).
extern cl_idecoded_float integer_decode_float (const cl_F& x);
// scale_float(x,delta) liefert x*2^delta, wo x ein Float ist.
extern cl_F scale_float (const cl_F& x, sintL delta);
extern cl_F scale_float (const cl_F& x, const cl_I& delta);
// signum(x) liefert (signum x), wo x ein Float ist.
extern cl_F signum (const cl_F& x);
// Returns the largest (most positive) floating point number in float format f.
extern cl_F most_positive_float (cl_float_format_t f);
//CL_REQUIRE(cl_F_mostpos)
// Returns the smallest (most negative) floating point number in float format f.
extern cl_F most_negative_float (cl_float_format_t f);
//CL_REQUIRE(cl_F_mostneg)
// Returns the least positive floating point number (i.e. > 0 but closest to 0)
// in float format f.
extern cl_F least_positive_float (cl_float_format_t f);
//CL_REQUIRE(cl_F_leastpos)
// Returns the least negative floating point number (i.e. < 0 but closest to 0)
// in float format f.
extern cl_F least_negative_float (cl_float_format_t f);
//CL_REQUIRE(cl_F_leastneg)
// Returns the smallest floating point number e > 0 such that 1+e != 1.
extern cl_F float_epsilon (cl_float_format_t f);
//CL_REQUIRE(cl_F_epspos)
// Returns the smallest floating point number e > 0 such that 1-e != 1.
extern cl_F float_negative_epsilon (cl_float_format_t f);
//CL_REQUIRE(cl_F_epsneg)
// Konversion zu einem C "float".
extern float cl_float_approx (const cl_F& x);
// Konversion zu einem C "double".
extern double cl_double_approx (const cl_F& x);
#ifdef WANT_OBFUSCATING_OPERATORS
// This could be optimized to use in-place operations.
inline cl_F& operator+= (cl_F& x, const cl_F& y) { return x = x + y; }
inline cl_F& operator++ /* prefix */ (cl_F& x) { return x = plus1(x); }
inline void operator++ /* postfix */ (cl_F& x, int dummy) { x = plus1(x); }
inline cl_F& operator-= (cl_F& x, const cl_F& y) { return x = x - y; }
inline cl_F& operator-- /* prefix */ (cl_F& x) { return x = minus1(x); }
inline void operator-- /* postfix */ (cl_F& x, int dummy) { x = minus1(x); }
inline cl_F& operator*= (cl_F& x, const cl_F& y) { return x = x * y; }
inline cl_F& operator/= (cl_F& x, const cl_F& y) { return x = x / y; }
#endif
CL_REQUIRE(cl_ieee)
// If this is true, floating point underflow returns zero instead of an error.
extern cl_boolean cl_inhibit_floating_point_underflow;
#endif /* _CL_FLOAT_H */
|