1 /* 2 streflop: STandalone REproducible FLOating-Point 3 Copyright 2006 Nicolas Brodu 4 2010 Mark Vejvoda 5 6 Code released according to the GNU Lesser General Public License 7 8 Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP, 9 and IBM MP lib. 10 Uses SoftFloat too. 11 12 Please read the history and copyright information in the documentation 13 provided with the source code 14 */ 15 16 // Included by the main streflop include file 17 // module broken apart for logical code separation 18 #ifndef STREFLOP_MATH_H 19 #define STREFLOP_MATH_H 20 21 // just in case, should already be included 22 #include "streflop.h" 23 24 // Names from the libm conversion 25 namespace streflop_libm { 26 using streflop::Simple; 27 using streflop::Double; 28 #ifdef Extended 29 using streflop::Extended; 30 #endif 31 32 extern Simple __ieee754_sqrtf(Simple x); 33 extern Simple __cbrtf(Simple x); 34 extern Simple __ieee754_hypotf(Simple x, Simple y); 35 extern Simple __ieee754_expf(Simple x); 36 extern Simple __ieee754_logf(Simple x); 37 extern Simple __ieee754_log2f(Simple x); 38 extern Simple __ieee754_exp2f(Simple x); 39 extern Simple __ieee754_log10f(Simple x); 40 extern Simple __ieee754_powf(Simple x, Simple y); 41 extern Simple __sinf(Simple x); 42 extern Simple __cosf(Simple x); 43 extern Simple __tanhf(Simple x); 44 extern Simple __tanf(Simple x); 45 extern Simple __ieee754_acosf(Simple x); 46 extern Simple __ieee754_asinf(Simple x); 47 extern Simple __atanf(Simple x); 48 extern Simple __ieee754_atan2f(Simple x, Simple y); 49 extern Simple __ieee754_coshf(Simple x); 50 extern Simple __ieee754_sinhf(Simple x); 51 extern Simple __ieee754_acoshf(Simple x); 52 extern Simple __asinhf(Simple x); 53 extern Simple __ieee754_atanhf(Simple x); 54 extern Simple __fabsf(Simple x); 55 extern Simple __floorf(Simple x); 56 extern Simple __ceilf(Simple x); 57 extern Simple __truncf(Simple x); 58 extern Simple __ieee754_fmodf(Simple x, Simple y); 59 extern Simple __ieee754_remainderf(Simple x, Simple y); 60 extern Simple __remquof(Simple x, Simple y, int *quo); 61 extern Simple __rintf(Simple x); 62 extern long int __lrintf(Simple x); 63 extern long long int __llrintf(Simple x); 64 extern Simple __roundf(Simple x); 65 extern long int __lroundf(Simple x); 66 extern long long int __llroundf(Simple x); 67 extern Simple __nearbyintf(Simple x); 68 extern Simple __frexpf(Simple x, int *exp); 69 extern Simple __ldexpf(Simple value, int exp); 70 extern Simple __logbf(Simple x); 71 extern int __ilogbf(Simple x); 72 extern Simple __copysignf(Simple x); 73 extern int __signbitf(Simple x); 74 extern Simple __nextafterf(Simple x, Simple y); 75 extern Simple __expm1f(Simple x); 76 extern Simple __log1pf(Simple x); 77 extern Simple __erff(Simple x); 78 extern Simple __ieee754_j0f(Simple x); 79 extern Simple __ieee754_j1f(Simple x); 80 extern Simple __ieee754_jnf(int n, Simple x); 81 extern Simple __ieee754_y0f(Simple x); 82 extern Simple __ieee754_y1f(Simple x); 83 extern Simple __ieee754_ynf(int n, Simple x); 84 extern Simple __scalbnf(Simple x, int n); 85 extern Simple __scalblnf(Simple x, long int n); 86 extern int __fpclassifyf(Simple x); 87 extern int __isnanf(Simple x); 88 extern int __isinff(Simple x); 89 extern Double __ieee754_sqrt(Double x); 90 extern Double __cbrt(Double x); 91 extern Double __ieee754_hypot(Double x, Double y); 92 extern Double __ieee754_exp(Double x); 93 extern Double __ieee754_log(Double x); 94 extern Double __ieee754_log2(Double x); 95 extern Double __ieee754_exp2(Double x); 96 extern Double __ieee754_log10(Double x); 97 extern Double __ieee754_pow(Double x, Double y); 98 extern Double __sin(Double x); 99 extern Double __cos(Double x); 100 extern Double tan(Double x); 101 extern Double __ieee754_acos(Double x); 102 extern Double __ieee754_asin(Double x); 103 extern Double atan(Double x); 104 extern Double __ieee754_atan2(Double x, Double y); 105 extern Double __ieee754_cosh(Double x); 106 extern Double __ieee754_sinh(Double x); 107 extern Double __tanh(Double x); 108 extern Double __ieee754_acosh(Double x); 109 extern Double __asinh(Double x); 110 extern Double __ieee754_atanh(Double x); 111 extern Double __fabs(Double x); 112 extern Double __floor(Double x); 113 extern Double __ceil(Double x); 114 extern Double __trunc(Double x); 115 extern Double __ieee754_fmod(Double x, Double y); 116 extern Double __ieee754_remainder(Double x, Double y); 117 extern Double __remquo(Double x, Double y, int *quo); 118 extern Double __rint(Double x); 119 extern long int __lrint(Double x); 120 extern long long int __llrint(Double x); 121 extern Double __round(Double x); 122 extern long int __lround(Double x); 123 extern long long int __llround(Double x); 124 extern Double __nearbyint(Double x); 125 extern Double __frexp(Double x, int *exp); 126 extern Double __ldexp(Double value, int exp); 127 extern Double __logb(Double x); 128 extern int __ilogb(Double x); 129 extern Double __copysign(Double x); 130 extern int __signbit(Double x); 131 extern Double __nextafter(Double x, Double y); 132 extern Double __expm1(Double x); 133 extern Double __log1p(Double x); 134 extern Double __erf(Double x); 135 extern Double __ieee754_j0(Double x); 136 extern Double __ieee754_j1(Double x); 137 extern Double __ieee754_jn(int n, Double x); 138 extern Double __ieee754_y0(Double x); 139 extern Double __ieee754_y1(Double x); 140 extern Double __ieee754_yn(int n, Double x); 141 extern Double __scalbn(Double x, int n); 142 extern Double __scalbln(Double x, long int n); 143 extern int __fpclassify(Double x); 144 extern int __isnanl(Double x); 145 extern int __isinf(Double x); 146 #ifdef Extended 147 extern Extended __ieee754_sqrtl(Extended x); 148 extern Extended __cbrtl(Extended x); 149 extern Extended __ieee754_hypotl(Extended x, Extended y); 150 extern Extended __ieee754_expl(Extended x); 151 extern Extended __ieee754_logl(Extended x); 152 extern Extended __sinl(Extended x); 153 extern Extended __cosl(Extended x); 154 extern Extended __tanl(Extended x); 155 extern Extended __ieee754_asinl(Extended x); 156 extern Extended __atanl(Extended x); 157 extern Extended __ieee754_atan2l(Extended x, Extended y); 158 extern Extended __ieee754_coshl(Extended x); 159 extern Extended __ieee754_sinhl(Extended x); 160 extern Extended __tanhl(Extended x); 161 extern Extended __ieee754_acoshl(Extended x); 162 extern Extended __asinhl(Extended x); 163 extern Extended __ieee754_atanhl(Extended x); 164 extern Extended __fabsl(Extended x); 165 extern Extended __floorl(Extended x); 166 extern Extended __ceill(Extended x); 167 extern Extended __truncl(Extended x); 168 extern Extended __ieee754_fmodl(Extended x, Extended y); 169 extern Extended __ieee754_remainderl(Extended x, Extended y); 170 extern Extended __remquol(Extended x, Extended y, int *quo); 171 extern Extended __rintl(Extended x); 172 extern long int __lrintl(Extended x); 173 extern long long int __llrintl(Extended x); 174 extern Extended __roundl(Extended x); 175 extern long int __lroundl(Extended x); 176 extern long long int __llroundl(Extended x); 177 extern Extended __nearbyintl(Extended x); 178 extern Extended __frexpl(Extended x, int *exp); 179 extern Extended __ldexpl(Extended value, int exp); 180 extern Extended __logbl(Extended x); 181 extern int __ilogbl(Extended x); 182 extern Extended __copysignl(Extended x); 183 extern int __signbitl(Extended x); 184 extern Extended __nextafterl(Extended x, Extended y); 185 extern Extended __expm1l(Extended x); 186 extern Extended __log1pl(Extended x); 187 extern Extended __erfl(Extended x); 188 extern Extended __ieee754_j0l(Extended x); 189 extern Extended __ieee754_j1l(Extended x); 190 extern Extended __ieee754_jnl(int n, Extended x); 191 extern Extended __ieee754_y0l(Extended x); 192 extern Extended __ieee754_y1l(Extended x); 193 extern Extended __ieee754_ynl(int n, Extended x); 194 extern Extended __scalbnl(Extended x, int n); 195 extern Extended __scalblnl(Extended x, long int n); 196 extern int __fpclassifyl(Extended x); 197 extern int __isnanl(Extended x); 198 extern int __isinfl(Extended x); 199 #endif // Extended 200 } 201 202 203 // Wrappers in our own namespace 204 namespace streflop { 205 206 // Stolen from math.h. All floating-point numbers can be put in one of these categories. 207 enum 208 { 209 STREFLOP_FP_NAN = 0, 210 STREFLOP_FP_INFINITE = 1, 211 STREFLOP_FP_ZERO = 2, 212 STREFLOP_FP_SUBNORMAL = 3, 213 STREFLOP_FP_NORMAL = 4 214 }; 215 216 217 // Simple and double are present in all configurations 218 sqrt(Simple x)219 inline Simple sqrt(Simple x) {return streflop_libm::__ieee754_sqrtf(x);} cbrt(Simple x)220 inline Simple cbrt(Simple x) {return streflop_libm::__cbrtf(x);} hypot(Simple x,Simple y)221 inline Simple hypot(Simple x, Simple y) {return streflop_libm::__ieee754_hypotf(x,y);} 222 exp(Simple x)223 inline Simple exp(Simple x) {return streflop_libm::__ieee754_expf(x);} log(Simple x)224 inline Simple log(Simple x) {return streflop_libm::__ieee754_logf(x);} log2(Simple x)225 inline Simple log2(Simple x) {return streflop_libm::__ieee754_log2f(x);} exp2(Simple x)226 inline Simple exp2(Simple x) {return streflop_libm::__ieee754_exp2f(x);} log10(Simple x)227 inline Simple log10(Simple x) {return streflop_libm::__ieee754_log10f(x);} pow(Simple x,Simple y)228 inline Simple pow(Simple x, Simple y) {return streflop_libm::__ieee754_powf(x,y);} 229 sin(Simple x)230 inline Simple sin(Simple x) {return streflop_libm::__sinf(x);} cos(Simple x)231 inline Simple cos(Simple x) {return streflop_libm::__cosf(x);} tan(Simple x)232 inline Simple tan(Simple x) {return streflop_libm::__tanf(x);} acos(Simple x)233 inline Simple acos(Simple x) {return streflop_libm::__ieee754_acosf(x);} asin(Simple x)234 inline Simple asin(Simple x) {return streflop_libm::__ieee754_asinf(x);} atan(Simple x)235 inline Simple atan(Simple x) {return streflop_libm::__atanf(x);} atan2(Simple x,Simple y)236 inline Simple atan2(Simple x, Simple y) {return streflop_libm::__ieee754_atan2f(x,y);} 237 cosh(Simple x)238 inline Simple cosh(Simple x) {return streflop_libm::__ieee754_coshf(x);} sinh(Simple x)239 inline Simple sinh(Simple x) {return streflop_libm::__ieee754_sinhf(x);} tanh(Simple x)240 inline Simple tanh(Simple x) {return streflop_libm::__tanhf(x);} acosh(Simple x)241 inline Simple acosh(Simple x) {return streflop_libm::__ieee754_acoshf(x);} asinh(Simple x)242 inline Simple asinh(Simple x) {return streflop_libm::__asinhf(x);} atanh(Simple x)243 inline Simple atanh(Simple x) {return streflop_libm::__ieee754_atanhf(x);} 244 fabs(Simple x)245 inline Simple fabs(Simple x) {return streflop_libm::__fabsf(x);} floor(Simple x)246 inline Simple floor(Simple x) {return streflop_libm::__floorf(x);} ceil(Simple x)247 inline Simple ceil(Simple x) {return streflop_libm::__ceilf(x);} trunc(Simple x)248 inline Simple trunc(Simple x) {return streflop_libm::__truncf(x);} fmod(Simple x,Simple y)249 inline Simple fmod(Simple x, Simple y) {return streflop_libm::__ieee754_fmodf(x,y);} remainder(Simple x,Simple y)250 inline Simple remainder(Simple x, Simple y) {return streflop_libm::__ieee754_remainderf(x,y);} remquo(Simple x,Simple y,int * quo)251 inline Simple remquo(Simple x, Simple y, int *quo) {return streflop_libm::__remquof(x,y,quo);} rint(Simple x)252 inline Simple rint(Simple x) {return streflop_libm::__rintf(x);} lrint(Simple x)253 inline long int lrint(Simple x) {return streflop_libm::__lrintf(x);} llrint(Simple x)254 inline long long int llrint(Simple x) {return streflop_libm::__llrintf(x);} round(Simple x)255 inline Simple round(Simple x) {return streflop_libm::__roundf(x);} lround(Simple x)256 inline long int lround(Simple x) {return streflop_libm::__lroundf(x);} llround(Simple x)257 inline long long int llround(Simple x) {return streflop_libm::__llroundf(x);} nearbyint(Simple x)258 inline Simple nearbyint(Simple x) {return streflop_libm::__nearbyintf(x);} 259 frexp(Simple x,int * exp)260 inline Simple frexp(Simple x, int *exp) {return streflop_libm::__frexpf(x,exp);} ldexp(Simple value,int exp)261 inline Simple ldexp(Simple value, int exp) {return streflop_libm::__ldexpf(value,exp);} logb(Simple x)262 inline Simple logb(Simple x) {return streflop_libm::__logbf(x);} ilogb(Simple x)263 inline int ilogb(Simple x) {return streflop_libm::__ilogbf(x);} copysign(Simple x)264 inline Simple copysign(Simple x) {return streflop_libm::__copysignf(x);} 265 #undef signbit signbit(Simple x)266 inline int signbit (Simple x) {return streflop_libm::__signbitf(x);} nextafter(Simple x,Simple y)267 inline Simple nextafter(Simple x, Simple y) {return streflop_libm::__nextafterf(x,y);} 268 expm1(Simple x)269 inline Simple expm1(Simple x) {return streflop_libm::__expm1f(x);} log1p(Simple x)270 inline Simple log1p(Simple x) {return streflop_libm::__log1pf(x);} erf(Simple x)271 inline Simple erf(Simple x) {return streflop_libm::__erff(x);} j0(Simple x)272 inline Simple j0(Simple x) {return streflop_libm::__ieee754_j0f(x);} j1(Simple x)273 inline Simple j1(Simple x) {return streflop_libm::__ieee754_j1f(x);} jn(int n,Simple x)274 inline Simple jn(int n, Simple x) {return streflop_libm::__ieee754_jnf(n,x);} y0(Simple x)275 inline Simple y0(Simple x) {return streflop_libm::__ieee754_y0f(x);} y1(Simple x)276 inline Simple y1(Simple x) {return streflop_libm::__ieee754_y1f(x);} yn(int n,Simple x)277 inline Simple yn(int n, Simple x) {return streflop_libm::__ieee754_ynf(n,x);} scalbn(Simple x,int n)278 inline Simple scalbn(Simple x, int n) {return streflop_libm::__scalbnf(x,n);} scalbln(Simple x,long int n)279 inline Simple scalbln(Simple x, long int n) {return streflop_libm::__scalblnf(x,n);} 280 281 #undef fpclassify fpclassify(Simple x)282 inline int fpclassify(Simple x) {return streflop_libm::__fpclassifyf(x);} 283 #undef isnan isnan(Simple x)284 inline int isnan(Simple x) {return streflop_libm::__isnanf(x);} 285 #undef isinf isinf(Simple x)286 inline int isinf(Simple x) {return streflop_libm::__isinff(x);} 287 #undef isfinite isfinite(Simple x)288 inline int isfinite(Simple x) {return !(isnan(x) || isinf(x));} 289 290 // Stolen from math.h and inlined instead of macroized. 291 // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ 292 #undef isnormal isnormal(Simple x)293 inline int isnormal(Simple x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} 294 295 // Constants user may set 296 extern const Simple SimplePositiveInfinity; 297 extern const Simple SimpleNegativeInfinity; 298 // Non-signaling NaN used for returning such results 299 // Standard lets a large room for implementing different kinds of NaN 300 // These NaN can be used for custom purposes 301 // Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers! 302 // Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean. 303 extern const Simple SimpleNaN; 304 305 /** Generic C99 "macros" for unordered comparison 306 Defined as inlined for each type, thanks to C++ overloading 307 */ 308 #if defined isunordered 309 #undef isunordered 310 #endif // defined isunordered isunordered(Simple x,Simple y)311 inline bool isunordered(Simple x, Simple y) { 312 return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify(y) == STREFLOP_FP_NAN); 313 } 314 #if defined isgreater 315 #undef isgreater 316 #endif // defined isgreater isgreater(Simple x,Simple y)317 inline bool isgreater(Simple x, Simple y) { 318 return (!isunordered(x,y)) && (x > y); 319 } 320 #if defined isgreaterequal 321 #undef isgreaterequal 322 #endif // defined isgreaterequal isgreaterequal(Simple x,Simple y)323 inline bool isgreaterequal(Simple x, Simple y) { 324 return (!isunordered(x,y)) && (x >= y); 325 } 326 #if defined isless 327 #undef isless 328 #endif // defined isless isless(Simple x,Simple y)329 inline bool isless(Simple x, Simple y) { 330 return (!isunordered(x,y)) && (x < y); 331 } 332 #if defined islessequal 333 #undef islessequal 334 #endif // defined islessequal islessequal(Simple x,Simple y)335 inline bool islessequal(Simple x, Simple y) { 336 return (!isunordered(x,y)) && (x <= y); 337 } 338 #if defined islessgreater 339 #undef islessgreater 340 #endif // defined islessgreater islessgreater(Simple x,Simple y)341 inline bool islessgreater(Simple x, Simple y) { 342 return (!isunordered(x,y)) && ((x < y) || (x > y)); 343 } 344 345 346 // Add xxxf alias to ease porting existing code to streflop 347 // Additionally, using xxxf(number) avoids potential confusion 348 sqrtf(Simple x)349 inline Simple sqrtf(Simple x) {return sqrt(x);} cbrtf(Simple x)350 inline Simple cbrtf(Simple x) {return cbrt(x);} hypotf(Simple x,Simple y)351 inline Simple hypotf(Simple x, Simple y) {return hypot(x, y);} 352 expf(Simple x)353 inline Simple expf(Simple x) {return exp(x);} logf(Simple x)354 inline Simple logf(Simple x) {return log(x);} log2f(Simple x)355 inline Simple log2f(Simple x) {return log2(x);} exp2f(Simple x)356 inline Simple exp2f(Simple x) {return exp2(x);} log10f(Simple x)357 inline Simple log10f(Simple x) {return log10(x);} powf(Simple x,Simple y)358 inline Simple powf(Simple x, Simple y) {return pow(x, y);} 359 sinf(Simple x)360 inline Simple sinf(Simple x) {return sin(x);} cosf(Simple x)361 inline Simple cosf(Simple x) {return cos(x);} tanf(Simple x)362 inline Simple tanf(Simple x) {return tan(x);} acosf(Simple x)363 inline Simple acosf(Simple x) {return acos(x);} asinf(Simple x)364 inline Simple asinf(Simple x) {return asin(x);} atanf(Simple x)365 inline Simple atanf(Simple x) {return atan(x);} atan2f(Simple x,Simple y)366 inline Simple atan2f(Simple x, Simple y) {return atan2(x, y);} 367 coshf(Simple x)368 inline Simple coshf(Simple x) {return cosh(x);} sinhf(Simple x)369 inline Simple sinhf(Simple x) {return sinh(x);} tanhf(Simple x)370 inline Simple tanhf(Simple x) {return tanh(x);} acoshf(Simple x)371 inline Simple acoshf(Simple x) {return acosh(x);} asinhf(Simple x)372 inline Simple asinhf(Simple x) {return asinh(x);} atanhf(Simple x)373 inline Simple atanhf(Simple x) {return atanh(x);} 374 fabsf(Simple x)375 inline Simple fabsf(Simple x) {return fabs(x);} floorf(Simple x)376 inline Simple floorf(Simple x) {return floor(x);} ceilf(Simple x)377 inline Simple ceilf(Simple x) {return ceil(x);} truncf(Simple x)378 inline Simple truncf(Simple x) {return trunc(x);} fmodf(Simple x,Simple y)379 inline Simple fmodf(Simple x, Simple y) {return fmod(x,y);} remainderf(Simple x,Simple y)380 inline Simple remainderf(Simple x, Simple y) {return remainder(x,y);} remquof(Simple x,Simple y,int * quo)381 inline Simple remquof(Simple x, Simple y, int *quo) {return remquo(x, y, quo);} rintf(Simple x)382 inline Simple rintf(Simple x) {return rint(x);} lrintf(Simple x)383 inline long int lrintf(Simple x) {return lrint(x);} llrintf(Simple x)384 inline long long int llrintf(Simple x) {return llrint(x);} roundf(Simple x)385 inline Simple roundf(Simple x) {return round(x);} lroundf(Simple x)386 inline long int lroundf(Simple x) {return lround(x);} llroundf(Simple x)387 inline long long int llroundf(Simple x) {return llround(x);} nearbyintf(Simple x)388 inline Simple nearbyintf(Simple x) {return nearbyint(x);} 389 frexpf(Simple x,int * exp)390 inline Simple frexpf(Simple x, int *exp) {return frexp(x, exp);} ldexpf(Simple value,int exp)391 inline Simple ldexpf(Simple value, int exp) {return ldexp(value,exp);} logbf(Simple x)392 inline Simple logbf(Simple x) {return logb(x);} ilogbf(Simple x)393 inline int ilogbf(Simple x) {return ilogb(x);} copysignf(Simple x)394 inline Simple copysignf(Simple x) {return copysign(x);} signbitf(Simple x)395 inline int signbitf(Simple x) {return signbit(x);} nextafterf(Simple x,Simple y)396 inline Simple nextafterf(Simple x, Simple y) {return nextafter(x, y);} 397 expm1f(Simple x)398 inline Simple expm1f(Simple x) {return expm1(x);} log1pf(Simple x)399 inline Simple log1pf(Simple x) {return log1p(x);} erff(Simple x)400 inline Simple erff(Simple x) {return erf(x);} j0f(Simple x)401 inline Simple j0f(Simple x) {return j0(x);} j1f(Simple x)402 inline Simple j1f(Simple x) {return j1(x);} jnf(int n,Simple x)403 inline Simple jnf(int n, Simple x) {return jn(n, x);} y0f(Simple x)404 inline Simple y0f(Simple x) {return y0(x);} y1f(Simple x)405 inline Simple y1f(Simple x) {return y1(x);} ynf(int n,Simple x)406 inline Simple ynf(int n, Simple x) {return yn(n, x);} scalbnf(Simple x,int n)407 inline Simple scalbnf(Simple x, int n) {return scalbn(x, n);} scalblnf(Simple x,long int n)408 inline Simple scalblnf(Simple x, long int n) {return scalbln(x, n);} 409 fpclassifyf(Simple x)410 inline int fpclassifyf(Simple x) {return fpclassify(x);} isnanf(Simple x)411 inline int isnanf(Simple x) {return isnan(x);} isinff(Simple x)412 inline int isinff(Simple x) {return isinf(x);} isfinitef(Simple x)413 inline int isfinitef(Simple x) {return isfinite(x);} isnormalf(Simple x)414 inline int isnormalf(Simple x) {return isnormal(x);} 415 isunorderedf(Simple x,Simple y)416 inline bool isunorderedf(Simple x, Simple y) {return isunordered(x, y);} isgreaterf(Simple x,Simple y)417 inline bool isgreaterf(Simple x, Simple y) {return isgreater(x, y);} isgreaterequalf(Simple x,Simple y)418 inline bool isgreaterequalf(Simple x, Simple y) {return isgreaterequalf(x, y);} islessf(Simple x,Simple y)419 inline bool islessf(Simple x, Simple y) {return isless(x, y);} islessequalf(Simple x,Simple y)420 inline bool islessequalf(Simple x, Simple y) {return islessequal(x, y);} islessgreaterf(Simple x,Simple y)421 inline bool islessgreaterf(Simple x, Simple y) {return islessgreater(x, y);} 422 423 424 // Declare Double functions 425 // Simple and double are present in all configurations 426 sqrt(Double x)427 inline Double sqrt(Double x) {return streflop_libm::__ieee754_sqrt(x);} cbrt(Double x)428 inline Double cbrt(Double x) {return streflop_libm::__cbrt(x);} hypot(Double x,Double y)429 inline Double hypot(Double x, Double y) {return streflop_libm::__ieee754_hypot(x,y);} 430 exp(Double x)431 inline Double exp(Double x) {return streflop_libm::__ieee754_exp(x);} log(Double x)432 inline Double log(Double x) {return streflop_libm::__ieee754_log(x);} log2(Double x)433 inline Double log2(Double x) {return streflop_libm::__ieee754_log2(x);} exp2(Double x)434 inline Double exp2(Double x) {return streflop_libm::__ieee754_exp2(x);} log10(Double x)435 inline Double log10(Double x) {return streflop_libm::__ieee754_log10(x);} pow(Double x,Double y)436 inline Double pow(Double x, Double y) {return streflop_libm::__ieee754_pow(x,y);} 437 sin(Double x)438 inline Double sin(Double x) {return streflop_libm::__sin(x);} cos(Double x)439 inline Double cos(Double x) {return streflop_libm::__cos(x);} tan(Double x)440 inline Double tan(Double x) {return streflop_libm::tan(x);} acos(Double x)441 inline Double acos(Double x) {return streflop_libm::__ieee754_acos(x);} asin(Double x)442 inline Double asin(Double x) {return streflop_libm::__ieee754_asin(x);} atan(Double x)443 inline Double atan(Double x) {return streflop_libm::atan(x);} atan2(Double x,Double y)444 inline Double atan2(Double x, Double y) {return streflop_libm::__ieee754_atan2(x,y);} 445 cosh(Double x)446 inline Double cosh(Double x) {return streflop_libm::__ieee754_cosh(x);} sinh(Double x)447 inline Double sinh(Double x) {return streflop_libm::__ieee754_sinh(x);} tanh(Double x)448 inline Double tanh(Double x) {return streflop_libm::__tanh(x);} acosh(Double x)449 inline Double acosh(Double x) {return streflop_libm::__ieee754_acosh(x);} asinh(Double x)450 inline Double asinh(Double x) {return streflop_libm::__asinh(x);} atanh(Double x)451 inline Double atanh(Double x) {return streflop_libm::__ieee754_atanh(x);} 452 fabs(Double x)453 inline Double fabs(Double x) {return streflop_libm::__fabs(x);} floor(Double x)454 inline Double floor(Double x) {return streflop_libm::__floor(x);} ceil(Double x)455 inline Double ceil(Double x) {return streflop_libm::__ceil(x);} trunc(Double x)456 inline Double trunc(Double x) {return streflop_libm::__trunc(x);} fmod(Double x,Double y)457 inline Double fmod(Double x, Double y) {return streflop_libm::__ieee754_fmod(x,y);} remainder(Double x,Double y)458 inline Double remainder(Double x, Double y) {return streflop_libm::__ieee754_remainder(x,y);} remquo(Double x,Double y,int * quo)459 inline Double remquo(Double x, Double y, int *quo) {return streflop_libm::__remquo(x,y,quo);} rint(Double x)460 inline Double rint(Double x) {return streflop_libm::__rint(x);} lrint(Double x)461 inline long int lrint(Double x) {return streflop_libm::__lrint(x);} llrint(Double x)462 inline long long int llrint(Double x) {return streflop_libm::__llrint(x);} round(Double x)463 inline Double round(Double x) {return streflop_libm::__round(x);} lround(Double x)464 inline long int lround(Double x) {return streflop_libm::__lround(x);} llround(Double x)465 inline long long int llround(Double x) {return streflop_libm::__llround(x);} nearbyint(Double x)466 inline Double nearbyint(Double x) {return streflop_libm::__nearbyint(x);} 467 frexp(Double x,int * exp)468 inline Double frexp(Double x, int *exp) {return streflop_libm::__frexp(x, exp);} ldexp(Double value,int exp)469 inline Double ldexp(Double value, int exp) {return streflop_libm::__ldexp(value,exp);} logb(Double x)470 inline Double logb(Double x) {return streflop_libm::__logb(x);} ilogb(Double x)471 inline int ilogb(Double x) {return streflop_libm::__ilogb(x);} copysign(Double x)472 inline Double copysign(Double x) {return streflop_libm::__copysign(x);} signbit(Double x)473 inline int signbit(Double x) {return streflop_libm::__signbit(x);} nextafter(Double x,Double y)474 inline Double nextafter(Double x, Double y) {return streflop_libm::__nextafter(x,y);} 475 expm1(Double x)476 inline Double expm1(Double x) {return streflop_libm::__expm1(x);} log1p(Double x)477 inline Double log1p(Double x) {return streflop_libm::__log1p(x);} erf(Double x)478 inline Double erf(Double x) {return streflop_libm::__erf(x);} j0(Double x)479 inline Double j0(Double x) {return streflop_libm::__ieee754_j0(x);} j1(Double x)480 inline Double j1(Double x) {return streflop_libm::__ieee754_j1(x);} jn(int n,Double x)481 inline Double jn(int n, Double x) {return streflop_libm::__ieee754_jn(n,x);} y0(Double x)482 inline Double y0(Double x) {return streflop_libm::__ieee754_y0(x);} y1(Double x)483 inline Double y1(Double x) {return streflop_libm::__ieee754_y1(x);} yn(int n,Double x)484 inline Double yn(int n, Double x) {return streflop_libm::__ieee754_yn(n,x);} scalbn(Double x,int n)485 inline Double scalbn(Double x, int n) {return streflop_libm::__scalbn(x,n);} scalbln(Double x,long int n)486 inline Double scalbln(Double x, long int n) {return streflop_libm::__scalbln(x,n);} 487 fpclassify(Double x)488 inline int fpclassify(Double x) {return streflop_libm::__fpclassify(x);} isnan(Double x)489 inline int isnan(Double x) {return streflop_libm::__isnanl(x);} isinf(Double x)490 inline int isinf(Double x) {return streflop_libm::__isinf(x);} isfinite(Double x)491 inline int isfinite(Double x) {return !(isnan(x) || isinf(x));} 492 493 // Stolen from math.h and inlined instead of macroized. 494 // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ isnormal(Double x)495 inline int isnormal(Double x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} 496 497 // Constants user may set 498 extern const Double DoublePositiveInfinity; 499 extern const Double DoubleNegativeInfinity; 500 // Non-signaling NaN used for returning such results 501 // Standard lets a large room for implementing different kinds of NaN 502 // These NaN can be used for custom purposes 503 // Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers! 504 // Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean. 505 extern const Double DoubleNaN; 506 507 /** Generic C99 "macros" for unordered comparison 508 Defined as inlined for each type, thanks to C++ overloading 509 */ isunordered(Double x,Double y)510 inline bool isunordered(Double x, Double y) { 511 return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN); 512 } isgreater(Double x,Double y)513 inline bool isgreater(Double x, Double y) { 514 return (!isunordered(x,y)) && (x > y); 515 } isgreaterequal(Double x,Double y)516 inline bool isgreaterequal(Double x, Double y) { 517 return (!isunordered(x,y)) && (x >= y); 518 } isless(Double x,Double y)519 inline bool isless(Double x, Double y) { 520 return (!isunordered(x,y)) && (x < y); 521 } islessequal(Double x,Double y)522 inline bool islessequal(Double x, Double y) { 523 return (!isunordered(x,y)) && (x <= y); 524 } islessgreater(Double x,Double y)525 inline bool islessgreater(Double x, Double y) { 526 return (!isunordered(x,y)) && ((x < y) || (x > y)); 527 } 528 529 // Extended are not always available 530 #ifdef Extended 531 cbrt(Extended x)532 inline Extended cbrt(Extended x) {return streflop_libm::__cbrtl(x);} hypot(Extended x,Extended y)533 inline Extended hypot(Extended x, Extended y) {return streflop_libm::__ieee754_hypotl(x,y);} 534 535 536 // Missing from libm: temporarily switch to Double and execute the Double version, 537 // then switch back to Extended and return the result sqrt(Extended x)538 inline Extended sqrt(Extended x) {streflop_init<Double>(); Double res = sqrt(Double(x)); streflop_init<Extended>(); return Extended(res);} 539 exp(Extended x)540 inline Extended exp(Extended x) {streflop_init<Double>(); Double res = exp(Double(x)); streflop_init<Extended>(); return Extended(res);} log(Extended x)541 inline Extended log(Extended x) {streflop_init<Double>(); Double res = log(Double(x)); streflop_init<Extended>(); return Extended(res);} log2(Extended x)542 inline Extended log2(Extended x) {streflop_init<Double>(); Double res = log2(Double(x)); streflop_init<Extended>(); return Extended(res);} exp2(Extended x)543 inline Extended exp2(Extended x) {streflop_init<Double>(); Double res = exp2(Double(x)); streflop_init<Extended>(); return Extended(res);} log10(Extended x)544 inline Extended log10(Extended x) {streflop_init<Double>(); Double res = log10(Double(x)); streflop_init<Extended>(); return Extended(res);} pow(Extended x,Extended y)545 inline Extended pow(Extended x, Extended y) {streflop_init<Double>(); Double res = pow(Double(x), Double(y)); streflop_init<Extended>(); return Extended(res);} sin(Extended x)546 inline Extended sin(Extended x) {streflop_init<Double>(); Double res = sin(Double(x)); streflop_init<Extended>(); return Extended(res);} cos(Extended x)547 inline Extended cos(Extended x) {streflop_init<Double>(); Double res = cos(Double(x)); streflop_init<Extended>(); return Extended(res);} tan(Extended x)548 inline Extended tan(Extended x) {streflop_init<Double>(); Double res = tan(Double(x)); streflop_init<Extended>(); return Extended(res);} acos(Extended x)549 inline Extended acos(Extended x) {streflop_init<Double>(); Double res = acos(Double(x)); streflop_init<Extended>(); return Extended(res);} asin(Extended x)550 inline Extended asin(Extended x) {streflop_init<Double>(); Double res = asin(Double(x)); streflop_init<Extended>(); return Extended(res);} atan(Extended x)551 inline Extended atan(Extended x) {streflop_init<Double>(); Double res = atan(Double(x)); streflop_init<Extended>(); return Extended(res);} atan2(Extended x,Extended y)552 inline Extended atan2(Extended x, Extended y) {streflop_init<Double>(); Double res = atan2(Double(x), Double(y)); streflop_init<Extended>(); return Extended(res);} 553 cosh(Extended x)554 inline Extended cosh(Extended x) {streflop_init<Double>(); Double res = cosh(Double(x)); streflop_init<Extended>(); return Extended(res);} sinh(Extended x)555 inline Extended sinh(Extended x) {streflop_init<Double>(); Double res = sinh(Double(x)); streflop_init<Extended>(); return Extended(res);} tanh(Extended x)556 inline Extended tanh(Extended x) {streflop_init<Double>(); Double res = tanh(Double(x)); streflop_init<Extended>(); return Extended(res);} acosh(Extended x)557 inline Extended acosh(Extended x) {streflop_init<Double>(); Double res = acosh(Double(x)); streflop_init<Extended>(); return Extended(res);} asinh(Extended x)558 inline Extended asinh(Extended x) {streflop_init<Double>(); Double res = asinh(Double(x)); streflop_init<Extended>(); return Extended(res);} atanh(Extended x)559 inline Extended atanh(Extended x) {streflop_init<Double>(); Double res = atanh(Double(x)); streflop_init<Extended>(); return Extended(res);} 560 561 expm1(Extended x)562 inline Extended expm1(Extended x) {streflop_init<Double>(); Double res = expm1(Double(x)); streflop_init<Extended>(); return Extended(res);} log1p(Extended x)563 inline Extended log1p(Extended x) {streflop_init<Double>(); Double res = log1p(Double(x)); streflop_init<Extended>(); return Extended(res);} erf(Extended x)564 inline Extended erf(Extended x) {streflop_init<Double>(); Double res = erf(Double(x)); streflop_init<Extended>(); return Extended(res);} j0(Extended x)565 inline Extended j0(Extended x) {streflop_init<Double>(); Double res = j0(Double(x)); streflop_init<Extended>(); return Extended(res);} j1(Extended x)566 inline Extended j1(Extended x) {streflop_init<Double>(); Double res = j1(Double(x)); streflop_init<Extended>(); return Extended(res);} jn(int n,Extended x)567 inline Extended jn(int n, Extended x) {streflop_init<Double>(); Double res = jn(n,Double(x)); streflop_init<Extended>(); return Extended(res);} y0(Extended x)568 inline Extended y0(Extended x) {streflop_init<Double>(); Double res = y0(Double(x)); streflop_init<Extended>(); return Extended(res);} y1(Extended x)569 inline Extended y1(Extended x) {streflop_init<Double>(); Double res = y1(Double(x)); streflop_init<Extended>(); return Extended(res);} yn(int n,Extended x)570 inline Extended yn(int n, Extended x) {streflop_init<Double>(); Double res = yn(n,Double(x)); streflop_init<Extended>(); return Extended(res);} scalbn(Extended x,int n)571 inline Extended scalbn(Extended x, int n) {streflop_init<Double>(); Double res = scalbn(Double(x),n); streflop_init<Extended>(); return Extended(res);} scalbln(Extended x,long int n)572 inline Extended scalbln(Extended x, long int n) {streflop_init<Double>(); Double res = scalbln(Double(x),n); streflop_init<Extended>(); return Extended(res);} 573 574 575 fabs(Extended x)576 inline Extended fabs(Extended x) {return streflop_libm::__fabsl(x);} floor(Extended x)577 inline Extended floor(Extended x) {return streflop_libm::__floorl(x);} ceil(Extended x)578 inline Extended ceil(Extended x) {return streflop_libm::__ceill(x);} trunc(Extended x)579 inline Extended trunc(Extended x) {return streflop_libm::__truncl(x);} fmod(Extended x,Extended y)580 inline Extended fmod(Extended x, Extended y) {return streflop_libm::__ieee754_fmodl(x,y);} remainder(Extended x,Extended y)581 inline Extended remainder(Extended x, Extended y) {return streflop_libm::__ieee754_remainderl(x,y);} remquo(Extended x,Extended y,int * quo)582 inline Extended remquo(Extended x, Extended y, int *quo) {return streflop_libm::__remquol(x,y,quo);} rint(Extended x)583 inline Extended rint(Extended x) {return streflop_libm::__rintl(x);} lrint(Extended x)584 inline long int lrint(Extended x) {return streflop_libm::__lrintl(x);} llrint(Extended x)585 inline long long int llrint(Extended x) {return streflop_libm::__llrintl(x);} round(Extended x)586 inline Extended round(Extended x) {return streflop_libm::__roundl(x);} lround(Extended x)587 inline long int lround(Extended x) {return streflop_libm::__lroundl(x);} llround(Extended x)588 inline long long int llround(Extended x) {return streflop_libm::__llroundl(x);} nearbyint(Extended x)589 inline Extended nearbyint(Extended x) {return streflop_libm::__nearbyintl(x);} 590 frexp(Extended x,int * exp)591 inline Extended frexp(Extended x, int *exp) {return streflop_libm::__frexpl(x,exp);} ldexp(Extended value,int exp)592 inline Extended ldexp(Extended value, int exp) {return streflop_libm::__ldexpl(value,exp);} logb(Extended x)593 inline Extended logb(Extended x) {return streflop_libm::__logbl(x);} ilogb(Extended x)594 inline int ilogb(Extended x) {return streflop_libm::__ilogbl(x);} copysign(Extended x)595 inline Extended copysign(Extended x) {return streflop_libm::__copysignl(x);} signbit(Extended x)596 inline int signbit (Extended x) {return streflop_libm::__signbitl(x);} nextafter(Extended x,Extended y)597 inline Extended nextafter(Extended x, Extended y) {return streflop_libm::__nextafterl(x,y);} 598 fpclassify(Extended x)599 inline int fpclassify(Extended x) {return streflop_libm::__fpclassifyl(x);} isnan(Extended x)600 inline int isnan(Extended x) {return streflop_libm::__isnanl(x);} isinf(Extended x)601 inline int isinf(Extended x) {return streflop_libm::__isinfl(x);} isfinite(Extended x)602 inline int isfinite(Extended x) {return !(isnan(x) || isinf(x));} 603 604 // Stolen from math.h and inlined instead of macroized. 605 // Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */ isnormal(Extended x)606 inline int isnormal(Extended x) {return fpclassify(x) == STREFLOP_FP_NORMAL;} 607 608 // Constants user may set 609 extern const Extended ExtendedPositiveInfinity; 610 extern const Extended ExtendedNegativeInfinity; 611 // Non-signaling NaN used for returning such results 612 // Standard lets a large room for implementing different kinds of NaN 613 // These NaN can be used for custom purposes 614 // Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers! 615 // Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean. 616 extern const Extended ExtendedNaN; 617 618 /** Generic C99 "macros" for unordered comparison 619 Defined as inlined for each type, thanks to C++ overloading 620 */ isunordered(Extended x,Extended y)621 inline bool isunordered(Extended x, Extended y) { 622 return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN); 623 } isgreater(Extended x,Extended y)624 inline bool isgreater(Extended x, Extended y) { 625 return (!isunordered(x,y)) && (x > y); 626 } isgreaterequal(Extended x,Extended y)627 inline bool isgreaterequal(Extended x, Extended y) { 628 return (!isunordered(x,y)) && (x >= y); 629 } isless(Extended x,Extended y)630 inline bool isless(Extended x, Extended y) { 631 return (!isunordered(x,y)) && (x < y); 632 } islessequal(Extended x,Extended y)633 inline bool islessequal(Extended x, Extended y) { 634 return (!isunordered(x,y)) && (x <= y); 635 } islessgreater(Extended x,Extended y)636 inline bool islessgreater(Extended x, Extended y) { 637 return (!isunordered(x,y)) && ((x < y) || (x > y)); 638 } 639 640 641 // Add xxxl alias to ease porting existing code to streflop 642 // Additionally, using xxxl(number) avoids potential confusion 643 sqrtl(Extended x)644 inline Extended sqrtl(Extended x) {return sqrt(x);} cbrtl(Extended x)645 inline Extended cbrtl(Extended x) {return cbrt(x);} hypotl(Extended x,Extended y)646 inline Extended hypotl(Extended x, Extended y) {return hypot(x, y);} 647 expl(Extended x)648 inline Extended expl(Extended x) {return exp(x);} logl(Extended x)649 inline Extended logl(Extended x) {return log(x);} log2l(Extended x)650 inline Extended log2l(Extended x) {return log2(x);} exp2l(Extended x)651 inline Extended exp2l(Extended x) {return exp2(x);} log10l(Extended x)652 inline Extended log10l(Extended x) {return log10(x);} powl(Extended x,Extended y)653 inline Extended powl(Extended x, Extended y) {return pow(x, y);} 654 sinl(Extended x)655 inline Extended sinl(Extended x) {return sin(x);} cosl(Extended x)656 inline Extended cosl(Extended x) {return cos(x);} tanl(Extended x)657 inline Extended tanl(Extended x) {return tan(x);} acosl(Extended x)658 inline Extended acosl(Extended x) {return acos(x);} asinl(Extended x)659 inline Extended asinl(Extended x) {return asin(x);} atanl(Extended x)660 inline Extended atanl(Extended x) {return atan(x);} atan2l(Extended x,Extended y)661 inline Extended atan2l(Extended x, Extended y) {return atan2(x, y);} 662 coshl(Extended x)663 inline Extended coshl(Extended x) {return cosh(x);} sinhl(Extended x)664 inline Extended sinhl(Extended x) {return sinh(x);} tanhl(Extended x)665 inline Extended tanhl(Extended x) {return tanh(x);} acoshl(Extended x)666 inline Extended acoshl(Extended x) {return acosh(x);} asinhl(Extended x)667 inline Extended asinhl(Extended x) {return asinh(x);} atanhl(Extended x)668 inline Extended atanhl(Extended x) {return atanh(x);} 669 fabsl(Extended x)670 inline Extended fabsl(Extended x) {return fabs(x);} floorl(Extended x)671 inline Extended floorl(Extended x) {return floor(x);} ceill(Extended x)672 inline Extended ceill(Extended x) {return ceil(x);} truncl(Extended x)673 inline Extended truncl(Extended x) {return trunc(x);} fmodl(Extended x,Extended y)674 inline Extended fmodl(Extended x, Extended y) {return fmod(x,y);} remainderl(Extended x,Extended y)675 inline Extended remainderl(Extended x, Extended y) {return remainder(x,y);} remquol(Extended x,Extended y,int * quo)676 inline Extended remquol(Extended x, Extended y, int *quo) {return remquo(x, y, quo);} rintl(Extended x)677 inline Extended rintl(Extended x) {return rint(x);} lrintl(Extended x)678 inline long int lrintl(Extended x) {return lrint(x);} llrintl(Extended x)679 inline long long int llrintl(Extended x) {return llrint(x);} roundl(Extended x)680 inline Extended roundl(Extended x) {return round(x);} lroundl(Extended x)681 inline long int lroundl(Extended x) {return lround(x);} llroundl(Extended x)682 inline long long int llroundl(Extended x) {return llround(x);} nearbyintl(Extended x)683 inline Extended nearbyintl(Extended x) {return nearbyint(x);} 684 frexpl(Extended x,int * exp)685 inline Extended frexpl(Extended x, int *exp) {return frexp(x, exp);} ldexpl(Extended value,int exp)686 inline Extended ldexpl(Extended value, int exp) {return ldexp(value,exp);} logbl(Extended x)687 inline Extended logbl(Extended x) {return logb(x);} ilogbl(Extended x)688 inline int ilogbl(Extended x) {return ilogb(x);} copysignl(Extended x)689 inline Extended copysignl(Extended x) {return copysign(x);} signbitl(Extended x)690 inline int signbitl(Extended x) {return signbit(x);} nextafterl(Extended x,Extended y)691