00001
00002 #include <math.h>
00003
00004 #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
00005 #include <ieeefp.h>
00006 #define fabsf(f) ((float)fabs(f))
00007 #else
00008 #include <fenv.h>
00009 #endif
00010
00011 #if defined(__OpenBSD__) || defined(__NetBSD__)
00012 #include <sys/param.h>
00013 #endif
00014
00015
00016
00017
00018
00019
00020
00021
00022 #if defined(HOST_SOLARIS) && (( HOST_SOLARIS <= 9 ) || ((HOST_SOLARIS >= 10) \
00023 && (__GNUC__ <= 4))) \
00024 || (defined(__OpenBSD__) && (OpenBSD < 200811))
00025
00026
00027
00028
00029
00030
00031
00032
00033 #if defined(__OpenBSD__)
00034 #define unordered(x, y) (isnan(x) || isnan(y))
00035 #endif
00036
00037 #ifdef __NetBSD__
00038 #ifndef isgreater
00039 #define isgreater(x, y) __builtin_isgreater(x, y)
00040 #endif
00041 #ifndef isgreaterequal
00042 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
00043 #endif
00044 #ifndef isless
00045 #define isless(x, y) __builtin_isless(x, y)
00046 #endif
00047 #ifndef islessequal
00048 #define islessequal(x, y) __builtin_islessequal(x, y)
00049 #endif
00050 #ifndef isunordered
00051 #define isunordered(x, y) __builtin_isunordered(x, y)
00052 #endif
00053 #endif
00054
00055
00056 #define isnormal(x) (fpclass(x) >= FP_NZERO)
00057 #define isgreater(x, y) ((!unordered(x, y)) && ((x) > (y)))
00058 #define isgreaterequal(x, y) ((!unordered(x, y)) && ((x) >= (y)))
00059 #define isless(x, y) ((!unordered(x, y)) && ((x) < (y)))
00060 #define islessequal(x, y) ((!unordered(x, y)) && ((x) <= (y)))
00061 #define isunordered(x,y) unordered(x, y)
00062 #endif
00063
00064 #if defined(__sun__) && !defined(NEED_LIBSUNMATH)
00065
00066 #ifndef isnan
00067 # define isnan(x) \
00068 (sizeof (x) == sizeof (long double) ? isnan_ld (x) \
00069 : sizeof (x) == sizeof (double) ? isnan_d (x) \
00070 : isnan_f (x))
00071 static inline int isnan_f (float x) { return x != x; }
00072 static inline int isnan_d (double x) { return x != x; }
00073 static inline int isnan_ld (long double x) { return x != x; }
00074 #endif
00075
00076 #ifndef isinf
00077 # define isinf(x) \
00078 (sizeof (x) == sizeof (long double) ? isinf_ld (x) \
00079 : sizeof (x) == sizeof (double) ? isinf_d (x) \
00080 : isinf_f (x))
00081 static inline int isinf_f (float x) { return isnan (x - x); }
00082 static inline int isinf_d (double x) { return isnan (x - x); }
00083 static inline int isinf_ld (long double x) { return isnan (x - x); }
00084 #endif
00085 #endif
00086
00087 typedef float float32;
00088 typedef double float64;
00089 #ifdef FLOATX80
00090 typedef long double floatx80;
00091 #endif
00092
00093 typedef union {
00094 float32 f;
00095 uint32_t i;
00096 } float32u;
00097 typedef union {
00098 float64 f;
00099 uint64_t i;
00100 } float64u;
00101 #ifdef FLOATX80
00102 typedef union {
00103 floatx80 f;
00104 struct {
00105 uint64_t low;
00106 uint16_t high;
00107 } i;
00108 } floatx80u;
00109 #endif
00110
00111
00112
00113
00114 #if (defined(_BSD) && !defined(__APPLE__)) || defined(HOST_SOLARIS)
00115 #if defined(__OpenBSD__)
00116 #define FE_RM FP_RM
00117 #define FE_RP FP_RP
00118 #define FE_RZ FP_RZ
00119 #endif
00120 enum {
00121 float_round_nearest_even = FP_RN,
00122 float_round_down = FP_RM,
00123 float_round_up = FP_RP,
00124 float_round_to_zero = FP_RZ
00125 };
00126 #elif defined(__arm__)
00127 enum {
00128 float_round_nearest_even = 0,
00129 float_round_down = 1,
00130 float_round_up = 2,
00131 float_round_to_zero = 3
00132 };
00133 #else
00134 enum {
00135 float_round_nearest_even = FE_TONEAREST,
00136 float_round_down = FE_DOWNWARD,
00137 float_round_up = FE_UPWARD,
00138 float_round_to_zero = FE_TOWARDZERO
00139 };
00140 #endif
00141
00142 typedef struct float_status {
00143 int float_rounding_mode;
00144 #ifdef FLOATX80
00145 int floatx80_rounding_precision;
00146 #endif
00147 } float_status;
00148
00149 void set_float_rounding_mode(int val STATUS_PARAM);
00150 #ifdef FLOATX80
00151 void set_floatx80_rounding_precision(int val STATUS_PARAM);
00152 #endif
00153
00154
00155
00156
00157 float32 int32_to_float32( int STATUS_PARAM);
00158 float32 uint32_to_float32( unsigned int STATUS_PARAM);
00159 float64 int32_to_float64( int STATUS_PARAM);
00160 float64 uint32_to_float64( unsigned int STATUS_PARAM);
00161 #ifdef FLOATX80
00162 floatx80 int32_to_floatx80( int STATUS_PARAM);
00163 #endif
00164 #ifdef FLOAT128
00165 float128 int32_to_float128( int STATUS_PARAM);
00166 #endif
00167 float32 int64_to_float32( int64_t STATUS_PARAM);
00168 float32 uint64_to_float32( uint64_t STATUS_PARAM);
00169 float64 int64_to_float64( int64_t STATUS_PARAM);
00170 float64 uint64_to_float64( uint64_t v STATUS_PARAM);
00171 #ifdef FLOATX80
00172 floatx80 int64_to_floatx80( int64_t STATUS_PARAM);
00173 #endif
00174 #ifdef FLOAT128
00175 float128 int64_to_float128( int64_t STATUS_PARAM);
00176 #endif
00177
00178
00179
00180
00181 int float32_to_int32( float32 STATUS_PARAM);
00182 int float32_to_int32_round_to_zero( float32 STATUS_PARAM);
00183 unsigned int float32_to_uint32( float32 a STATUS_PARAM);
00184 unsigned int float32_to_uint32_round_to_zero( float32 a STATUS_PARAM);
00185 int64_t float32_to_int64( float32 STATUS_PARAM);
00186 int64_t float32_to_int64_round_to_zero( float32 STATUS_PARAM);
00187 float64 float32_to_float64( float32 STATUS_PARAM);
00188 #ifdef FLOATX80
00189 floatx80 float32_to_floatx80( float32 STATUS_PARAM);
00190 #endif
00191 #ifdef FLOAT128
00192 float128 float32_to_float128( float32 STATUS_PARAM);
00193 #endif
00194
00195
00196
00197
00198 float32 float32_round_to_int( float32 STATUS_PARAM);
00199 INLINE float32 float32_add( float32 a, float32 b STATUS_PARAM)
00200 {
00201 return a + b;
00202 }
00203 INLINE float32 float32_sub( float32 a, float32 b STATUS_PARAM)
00204 {
00205 return a - b;
00206 }
00207 INLINE float32 float32_mul( float32 a, float32 b STATUS_PARAM)
00208 {
00209 return a * b;
00210 }
00211 INLINE float32 float32_div( float32 a, float32 b STATUS_PARAM)
00212 {
00213 return a / b;
00214 }
00215 float32 float32_rem( float32, float32 STATUS_PARAM);
00216 float32 float32_sqrt( float32 STATUS_PARAM);
00217 INLINE int float32_eq( float32 a, float32 b STATUS_PARAM)
00218 {
00219 return a == b;
00220 }
00221 INLINE int float32_le( float32 a, float32 b STATUS_PARAM)
00222 {
00223 return a <= b;
00224 }
00225 INLINE int float32_lt( float32 a, float32 b STATUS_PARAM)
00226 {
00227 return a < b;
00228 }
00229 INLINE int float32_eq_signaling( float32 a, float32 b STATUS_PARAM)
00230 {
00231 return a <= b && a >= b;
00232 }
00233 INLINE int float32_le_quiet( float32 a, float32 b STATUS_PARAM)
00234 {
00235 return islessequal(a, b);
00236 }
00237 INLINE int float32_lt_quiet( float32 a, float32 b STATUS_PARAM)
00238 {
00239 return isless(a, b);
00240 }
00241 INLINE int float32_unordered( float32 a, float32 b STATUS_PARAM)
00242 {
00243 return isunordered(a, b);
00244
00245 }
00246 int float32_compare( float32, float32 STATUS_PARAM );
00247 int float32_compare_quiet( float32, float32 STATUS_PARAM );
00248 int float32_is_signaling_nan( float32 );
00249 int float32_is_nan( float32 );
00250
00251 INLINE float32 float32_abs(float32 a)
00252 {
00253 return fabsf(a);
00254 }
00255
00256 INLINE float32 float32_chs(float32 a)
00257 {
00258 return -a;
00259 }
00260
00261 INLINE float32 float32_is_infinity(float32 a)
00262 {
00263 return fpclassify(a) == FP_INFINITE;
00264 }
00265
00266 INLINE float32 float32_is_neg(float32 a)
00267 {
00268 float32u u;
00269 u.f = a;
00270 return u.i >> 31;
00271 }
00272
00273 INLINE float32 float32_is_zero(float32 a)
00274 {
00275 return fpclassify(a) == FP_ZERO;
00276 }
00277
00278 INLINE float32 float32_scalbn(float32 a, int n)
00279 {
00280 return scalbnf(a, n);
00281 }
00282
00283
00284
00285
00286 int float64_to_int32( float64 STATUS_PARAM );
00287 int float64_to_int32_round_to_zero( float64 STATUS_PARAM );
00288 unsigned int float64_to_uint32( float64 STATUS_PARAM );
00289 unsigned int float64_to_uint32_round_to_zero( float64 STATUS_PARAM );
00290 int64_t float64_to_int64( float64 STATUS_PARAM );
00291 int64_t float64_to_int64_round_to_zero( float64 STATUS_PARAM );
00292 uint64_t float64_to_uint64( float64 STATUS_PARAM );
00293 uint64_t float64_to_uint64_round_to_zero( float64 STATUS_PARAM );
00294 float32 float64_to_float32( float64 STATUS_PARAM );
00295 #ifdef FLOATX80
00296 floatx80 float64_to_floatx80( float64 STATUS_PARAM );
00297 #endif
00298 #ifdef FLOAT128
00299 float128 float64_to_float128( float64 STATUS_PARAM );
00300 #endif
00301
00302
00303
00304
00305 float64 float64_round_to_int( float64 STATUS_PARAM );
00306 float64 float64_trunc_to_int( float64 STATUS_PARAM );
00307 INLINE float64 float64_add( float64 a, float64 b STATUS_PARAM)
00308 {
00309 return a + b;
00310 }
00311 INLINE float64 float64_sub( float64 a, float64 b STATUS_PARAM)
00312 {
00313 return a - b;
00314 }
00315 INLINE float64 float64_mul( float64 a, float64 b STATUS_PARAM)
00316 {
00317 return a * b;
00318 }
00319 INLINE float64 float64_div( float64 a, float64 b STATUS_PARAM)
00320 {
00321 return a / b;
00322 }
00323 float64 float64_rem( float64, float64 STATUS_PARAM );
00324 float64 float64_sqrt( float64 STATUS_PARAM );
00325 INLINE int float64_eq( float64 a, float64 b STATUS_PARAM)
00326 {
00327 return a == b;
00328 }
00329 INLINE int float64_le( float64 a, float64 b STATUS_PARAM)
00330 {
00331 return a <= b;
00332 }
00333 INLINE int float64_lt( float64 a, float64 b STATUS_PARAM)
00334 {
00335 return a < b;
00336 }
00337 INLINE int float64_eq_signaling( float64 a, float64 b STATUS_PARAM)
00338 {
00339 return a <= b && a >= b;
00340 }
00341 INLINE int float64_le_quiet( float64 a, float64 b STATUS_PARAM)
00342 {
00343 return islessequal(a, b);
00344 }
00345 INLINE int float64_lt_quiet( float64 a, float64 b STATUS_PARAM)
00346 {
00347 return isless(a, b);
00348
00349 }
00350 INLINE int float64_unordered( float64 a, float64 b STATUS_PARAM)
00351 {
00352 return isunordered(a, b);
00353
00354 }
00355 int float64_compare( float64, float64 STATUS_PARAM );
00356 int float64_compare_quiet( float64, float64 STATUS_PARAM );
00357 int float64_is_signaling_nan( float64 );
00358 int float64_is_nan( float64 );
00359
00360 INLINE float64 float64_abs(float64 a)
00361 {
00362 return fabs(a);
00363 }
00364
00365 INLINE float64 float64_chs(float64 a)
00366 {
00367 return -a;
00368 }
00369
00370 INLINE float64 float64_is_infinity(float64 a)
00371 {
00372 return fpclassify(a) == FP_INFINITE;
00373 }
00374
00375 INLINE float64 float64_is_neg(float64 a)
00376 {
00377 float64u u;
00378 u.f = a;
00379 return u.i >> 63;
00380 }
00381
00382 INLINE float64 float64_is_zero(float64 a)
00383 {
00384 return fpclassify(a) == FP_ZERO;
00385 }
00386
00387 INLINE float64 float64_scalbn(float64 a, int n)
00388 {
00389 return scalbn(a, n);
00390 }
00391
00392 #ifdef FLOATX80
00393
00394
00395
00396
00397 int floatx80_to_int32( floatx80 STATUS_PARAM );
00398 int floatx80_to_int32_round_to_zero( floatx80 STATUS_PARAM );
00399 int64_t floatx80_to_int64( floatx80 STATUS_PARAM);
00400 int64_t floatx80_to_int64_round_to_zero( floatx80 STATUS_PARAM);
00401 float32 floatx80_to_float32( floatx80 STATUS_PARAM );
00402 float64 floatx80_to_float64( floatx80 STATUS_PARAM );
00403 #ifdef FLOAT128
00404 float128 floatx80_to_float128( floatx80 STATUS_PARAM );
00405 #endif
00406
00407
00408
00409
00410 floatx80 floatx80_round_to_int( floatx80 STATUS_PARAM );
00411 INLINE floatx80 floatx80_add( floatx80 a, floatx80 b STATUS_PARAM)
00412 {
00413 return a + b;
00414 }
00415 INLINE floatx80 floatx80_sub( floatx80 a, floatx80 b STATUS_PARAM)
00416 {
00417 return a - b;
00418 }
00419 INLINE floatx80 floatx80_mul( floatx80 a, floatx80 b STATUS_PARAM)
00420 {
00421 return a * b;
00422 }
00423 INLINE floatx80 floatx80_div( floatx80 a, floatx80 b STATUS_PARAM)
00424 {
00425 return a / b;
00426 }
00427 floatx80 floatx80_rem( floatx80, floatx80 STATUS_PARAM );
00428 floatx80 floatx80_sqrt( floatx80 STATUS_PARAM );
00429 INLINE int floatx80_eq( floatx80 a, floatx80 b STATUS_PARAM)
00430 {
00431 return a == b;
00432 }
00433 INLINE int floatx80_le( floatx80 a, floatx80 b STATUS_PARAM)
00434 {
00435 return a <= b;
00436 }
00437 INLINE int floatx80_lt( floatx80 a, floatx80 b STATUS_PARAM)
00438 {
00439 return a < b;
00440 }
00441 INLINE int floatx80_eq_signaling( floatx80 a, floatx80 b STATUS_PARAM)
00442 {
00443 return a <= b && a >= b;
00444 }
00445 INLINE int floatx80_le_quiet( floatx80 a, floatx80 b STATUS_PARAM)
00446 {
00447 return islessequal(a, b);
00448 }
00449 INLINE int floatx80_lt_quiet( floatx80 a, floatx80 b STATUS_PARAM)
00450 {
00451 return isless(a, b);
00452
00453 }
00454 INLINE int floatx80_unordered( floatx80 a, floatx80 b STATUS_PARAM)
00455 {
00456 return isunordered(a, b);
00457
00458 }
00459 int floatx80_compare( floatx80, floatx80 STATUS_PARAM );
00460 int floatx80_compare_quiet( floatx80, floatx80 STATUS_PARAM );
00461 int floatx80_is_signaling_nan( floatx80 );
00462 int floatx80_is_nan( floatx80 );
00463
00464 INLINE floatx80 floatx80_abs(floatx80 a)
00465 {
00466 return fabsl(a);
00467 }
00468
00469 INLINE floatx80 floatx80_chs(floatx80 a)
00470 {
00471 return -a;
00472 }
00473
00474 INLINE floatx80 floatx80_is_infinity(floatx80 a)
00475 {
00476 return fpclassify(a) == FP_INFINITE;
00477 }
00478
00479 INLINE floatx80 floatx80_is_neg(floatx80 a)
00480 {
00481 floatx80u u;
00482 u.f = a;
00483 return u.i.high >> 15;
00484 }
00485
00486 INLINE floatx80 floatx80_is_zero(floatx80 a)
00487 {
00488 return fpclassify(a) == FP_ZERO;
00489 }
00490
00491 INLINE floatx80 floatx80_scalbn(floatx80 a, int n)
00492 {
00493 return scalbnl(a, n);
00494 }
00495
00496 #endif