724 lines
35 KiB
C++
724 lines
35 KiB
C++
/*
|
|
streflop: STandalone REproducible FLOating-Point
|
|
Copyright 2006 Nicolas Brodu
|
|
2010 Mark Vejvoda
|
|
|
|
Code released according to the GNU Lesser General Public License
|
|
|
|
Heavily relies on GNU Libm, itself depending on netlib fplibm, GNU MP,
|
|
and IBM MP lib.
|
|
Uses SoftFloat too.
|
|
|
|
Please read the history and copyright information in the documentation
|
|
provided with the source code
|
|
*/
|
|
|
|
// Included by the main streflop include file
|
|
// module broken apart for logical code separation
|
|
#ifndef STREFLOP_MATH_H
|
|
#define STREFLOP_MATH_H
|
|
|
|
// just in case, should already be included
|
|
#include "streflop.h"
|
|
|
|
// Names from the libm conversion
|
|
namespace streflop_libm {
|
|
using streflop::Simple;
|
|
using streflop::Double;
|
|
#ifdef Extended
|
|
using streflop::Extended;
|
|
#endif
|
|
|
|
extern Simple __ieee754_sqrtf(Simple x);
|
|
extern Simple __cbrtf(Simple x);
|
|
extern Simple __ieee754_hypotf(Simple x, Simple y);
|
|
extern Simple __ieee754_expf(Simple x);
|
|
extern Simple __ieee754_logf(Simple x);
|
|
extern Simple __ieee754_log2f(Simple x);
|
|
extern Simple __ieee754_exp2f(Simple x);
|
|
extern Simple __ieee754_log10f(Simple x);
|
|
extern Simple __ieee754_powf(Simple x, Simple y);
|
|
extern Simple __sinf(Simple x);
|
|
extern Simple __cosf(Simple x);
|
|
extern Simple __tanhf(Simple x);
|
|
extern Simple __tanf(Simple x);
|
|
extern Simple __ieee754_acosf(Simple x);
|
|
extern Simple __ieee754_asinf(Simple x);
|
|
extern Simple __atanf(Simple x);
|
|
extern Simple __ieee754_atan2f(Simple x, Simple y);
|
|
extern Simple __ieee754_coshf(Simple x);
|
|
extern Simple __ieee754_sinhf(Simple x);
|
|
extern Simple __ieee754_acoshf(Simple x);
|
|
extern Simple __asinhf(Simple x);
|
|
extern Simple __ieee754_atanhf(Simple x);
|
|
extern Simple __fabsf(Simple x);
|
|
extern Simple __floorf(Simple x);
|
|
extern Simple __ceilf(Simple x);
|
|
extern Simple __truncf(Simple x);
|
|
extern Simple __ieee754_fmodf(Simple x, Simple y);
|
|
extern Simple __ieee754_remainderf(Simple x, Simple y);
|
|
extern Simple __remquof(Simple x, Simple y, int *quo);
|
|
extern Simple __rintf(Simple x);
|
|
extern long int __lrintf(Simple x);
|
|
extern long long int __llrintf(Simple x);
|
|
extern Simple __roundf(Simple x);
|
|
extern long int __lroundf(Simple x);
|
|
extern long long int __llroundf(Simple x);
|
|
extern Simple __nearbyintf(Simple x);
|
|
extern Simple __frexpf(Simple x, int *exp);
|
|
extern Simple __ldexpf(Simple value, int exp);
|
|
extern Simple __logbf(Simple x);
|
|
extern int __ilogbf(Simple x);
|
|
extern Simple __copysignf(Simple x);
|
|
extern int __signbitf(Simple x);
|
|
extern Simple __nextafterf(Simple x, Simple y);
|
|
extern Simple __expm1f(Simple x);
|
|
extern Simple __log1pf(Simple x);
|
|
extern Simple __erff(Simple x);
|
|
extern Simple __ieee754_j0f(Simple x);
|
|
extern Simple __ieee754_j1f(Simple x);
|
|
extern Simple __ieee754_jnf(int n, Simple x);
|
|
extern Simple __ieee754_y0f(Simple x);
|
|
extern Simple __ieee754_y1f(Simple x);
|
|
extern Simple __ieee754_ynf(int n, Simple x);
|
|
extern Simple __scalbnf(Simple x, int n);
|
|
extern Simple __scalblnf(Simple x, long int n);
|
|
extern int __fpclassifyf(Simple x);
|
|
extern int __isnanf(Simple x);
|
|
extern int __isinff(Simple x);
|
|
extern Double __ieee754_sqrt(Double x);
|
|
extern Double __cbrt(Double x);
|
|
extern Double __ieee754_hypot(Double x, Double y);
|
|
extern Double __ieee754_exp(Double x);
|
|
extern Double __ieee754_log(Double x);
|
|
extern Double __ieee754_log2(Double x);
|
|
extern Double __ieee754_exp2(Double x);
|
|
extern Double __ieee754_log10(Double x);
|
|
extern Double __ieee754_pow(Double x, Double y);
|
|
extern Double __sin(Double x);
|
|
extern Double __cos(Double x);
|
|
extern Double tan(Double x);
|
|
extern Double __ieee754_acos(Double x);
|
|
extern Double __ieee754_asin(Double x);
|
|
extern Double atan(Double x);
|
|
extern Double __ieee754_atan2(Double x, Double y);
|
|
extern Double __ieee754_cosh(Double x);
|
|
extern Double __ieee754_sinh(Double x);
|
|
extern Double __tanh(Double x);
|
|
extern Double __ieee754_acosh(Double x);
|
|
extern Double __asinh(Double x);
|
|
extern Double __ieee754_atanh(Double x);
|
|
extern Double __fabs(Double x);
|
|
extern Double __floor(Double x);
|
|
extern Double __ceil(Double x);
|
|
extern Double __trunc(Double x);
|
|
extern Double __ieee754_fmod(Double x, Double y);
|
|
extern Double __ieee754_remainder(Double x, Double y);
|
|
extern Double __remquo(Double x, Double y, int *quo);
|
|
extern Double __rint(Double x);
|
|
extern long int __lrint(Double x);
|
|
extern long long int __llrint(Double x);
|
|
extern Double __round(Double x);
|
|
extern long int __lround(Double x);
|
|
extern long long int __llround(Double x);
|
|
extern Double __nearbyint(Double x);
|
|
extern Double __frexp(Double x, int *exp);
|
|
extern Double __ldexp(Double value, int exp);
|
|
extern Double __logb(Double x);
|
|
extern int __ilogb(Double x);
|
|
extern Double __copysign(Double x);
|
|
extern int __signbit(Double x);
|
|
extern Double __nextafter(Double x, Double y);
|
|
extern Double __expm1(Double x);
|
|
extern Double __log1p(Double x);
|
|
extern Double __erf(Double x);
|
|
extern Double __ieee754_j0(Double x);
|
|
extern Double __ieee754_j1(Double x);
|
|
extern Double __ieee754_jn(int n, Double x);
|
|
extern Double __ieee754_y0(Double x);
|
|
extern Double __ieee754_y1(Double x);
|
|
extern Double __ieee754_yn(int n, Double x);
|
|
extern Double __scalbn(Double x, int n);
|
|
extern Double __scalbln(Double x, long int n);
|
|
extern int __fpclassify(Double x);
|
|
extern int __isnanl(Double x);
|
|
extern int __isinf(Double x);
|
|
#ifdef Extended
|
|
extern Extended __ieee754_sqrtl(Extended x);
|
|
extern Extended __cbrtl(Extended x);
|
|
extern Extended __ieee754_hypotl(Extended x, Extended y);
|
|
extern Extended __ieee754_expl(Extended x);
|
|
extern Extended __ieee754_logl(Extended x);
|
|
extern Extended __sinl(Extended x);
|
|
extern Extended __cosl(Extended x);
|
|
extern Extended __tanl(Extended x);
|
|
extern Extended __ieee754_asinl(Extended x);
|
|
extern Extended __atanl(Extended x);
|
|
extern Extended __ieee754_atan2l(Extended x, Extended y);
|
|
extern Extended __ieee754_coshl(Extended x);
|
|
extern Extended __ieee754_sinhl(Extended x);
|
|
extern Extended __tanhl(Extended x);
|
|
extern Extended __ieee754_acoshl(Extended x);
|
|
extern Extended __asinhl(Extended x);
|
|
extern Extended __ieee754_atanhl(Extended x);
|
|
extern Extended __fabsl(Extended x);
|
|
extern Extended __floorl(Extended x);
|
|
extern Extended __ceill(Extended x);
|
|
extern Extended __truncl(Extended x);
|
|
extern Extended __ieee754_fmodl(Extended x, Extended y);
|
|
extern Extended __ieee754_remainderl(Extended x, Extended y);
|
|
extern Extended __remquol(Extended x, Extended y, int *quo);
|
|
extern Extended __rintl(Extended x);
|
|
extern long int __lrintl(Extended x);
|
|
extern long long int __llrintl(Extended x);
|
|
extern Extended __roundl(Extended x);
|
|
extern long int __lroundl(Extended x);
|
|
extern long long int __llroundl(Extended x);
|
|
extern Extended __nearbyintl(Extended x);
|
|
extern Extended __frexpl(Extended x, int *exp);
|
|
extern Extended __ldexpl(Extended value, int exp);
|
|
extern Extended __logbl(Extended x);
|
|
extern int __ilogbl(Extended x);
|
|
extern Extended __copysignl(Extended x);
|
|
extern int __signbitl(Extended x);
|
|
extern Extended __nextafterl(Extended x, Extended y);
|
|
extern Extended __expm1l(Extended x);
|
|
extern Extended __log1pl(Extended x);
|
|
extern Extended __erfl(Extended x);
|
|
extern Extended __ieee754_j0l(Extended x);
|
|
extern Extended __ieee754_j1l(Extended x);
|
|
extern Extended __ieee754_jnl(int n, Extended x);
|
|
extern Extended __ieee754_y0l(Extended x);
|
|
extern Extended __ieee754_y1l(Extended x);
|
|
extern Extended __ieee754_ynl(int n, Extended x);
|
|
extern Extended __scalbnl(Extended x, int n);
|
|
extern Extended __scalblnl(Extended x, long int n);
|
|
extern int __fpclassifyl(Extended x);
|
|
extern int __isnanl(Extended x);
|
|
extern int __isinfl(Extended x);
|
|
#endif // Extended
|
|
}
|
|
|
|
|
|
// Wrappers in our own namespace
|
|
namespace streflop {
|
|
|
|
// Stolen from math.h. All floating-point numbers can be put in one of these categories.
|
|
enum
|
|
{
|
|
STREFLOP_FP_NAN = 0,
|
|
STREFLOP_FP_INFINITE = 1,
|
|
STREFLOP_FP_ZERO = 2,
|
|
STREFLOP_FP_SUBNORMAL = 3,
|
|
STREFLOP_FP_NORMAL = 4
|
|
};
|
|
|
|
|
|
// Simple and double are present in all configurations
|
|
|
|
inline Simple sqrt(Simple x) {return streflop_libm::__ieee754_sqrtf(x);}
|
|
inline Simple cbrt(Simple x) {return streflop_libm::__cbrtf(x);}
|
|
inline Simple hypot(Simple x, Simple y) {return streflop_libm::__ieee754_hypotf(x,y);}
|
|
|
|
inline Simple exp(Simple x) {return streflop_libm::__ieee754_expf(x);}
|
|
inline Simple log(Simple x) {return streflop_libm::__ieee754_logf(x);}
|
|
inline Simple log2(Simple x) {return streflop_libm::__ieee754_log2f(x);}
|
|
inline Simple exp2(Simple x) {return streflop_libm::__ieee754_exp2f(x);}
|
|
inline Simple log10(Simple x) {return streflop_libm::__ieee754_log10f(x);}
|
|
inline Simple pow(Simple x, Simple y) {return streflop_libm::__ieee754_powf(x,y);}
|
|
|
|
inline Simple sin(Simple x) {return streflop_libm::__sinf(x);}
|
|
inline Simple cos(Simple x) {return streflop_libm::__cosf(x);}
|
|
inline Simple tan(Simple x) {return streflop_libm::__tanf(x);}
|
|
inline Simple acos(Simple x) {return streflop_libm::__ieee754_acosf(x);}
|
|
inline Simple asin(Simple x) {return streflop_libm::__ieee754_asinf(x);}
|
|
inline Simple atan(Simple x) {return streflop_libm::__atanf(x);}
|
|
inline Simple atan2(Simple x, Simple y) {return streflop_libm::__ieee754_atan2f(x,y);}
|
|
|
|
inline Simple cosh(Simple x) {return streflop_libm::__ieee754_coshf(x);}
|
|
inline Simple sinh(Simple x) {return streflop_libm::__ieee754_sinhf(x);}
|
|
inline Simple tanh(Simple x) {return streflop_libm::__tanhf(x);}
|
|
inline Simple acosh(Simple x) {return streflop_libm::__ieee754_acoshf(x);}
|
|
inline Simple asinh(Simple x) {return streflop_libm::__asinhf(x);}
|
|
inline Simple atanh(Simple x) {return streflop_libm::__ieee754_atanhf(x);}
|
|
|
|
inline Simple fabs(Simple x) {return streflop_libm::__fabsf(x);}
|
|
inline Simple floor(Simple x) {return streflop_libm::__floorf(x);}
|
|
inline Simple ceil(Simple x) {return streflop_libm::__ceilf(x);}
|
|
inline Simple trunc(Simple x) {return streflop_libm::__truncf(x);}
|
|
inline Simple fmod(Simple x, Simple y) {return streflop_libm::__ieee754_fmodf(x,y);}
|
|
inline Simple remainder(Simple x, Simple y) {return streflop_libm::__ieee754_remainderf(x,y);}
|
|
inline Simple remquo(Simple x, Simple y, int *quo) {return streflop_libm::__remquof(x,y,quo);}
|
|
inline Simple rint(Simple x) {return streflop_libm::__rintf(x);}
|
|
inline long int lrint(Simple x) {return streflop_libm::__lrintf(x);}
|
|
inline long long int llrint(Simple x) {return streflop_libm::__llrintf(x);}
|
|
inline Simple round(Simple x) {return streflop_libm::__roundf(x);}
|
|
inline long int lround(Simple x) {return streflop_libm::__lroundf(x);}
|
|
inline long long int llround(Simple x) {return streflop_libm::__llroundf(x);}
|
|
inline Simple nearbyint(Simple x) {return streflop_libm::__nearbyintf(x);}
|
|
|
|
inline Simple frexp(Simple x, int *exp) {return streflop_libm::__frexpf(x,exp);}
|
|
inline Simple ldexp(Simple value, int exp) {return streflop_libm::__ldexpf(value,exp);}
|
|
inline Simple logb(Simple x) {return streflop_libm::__logbf(x);}
|
|
inline int ilogb(Simple x) {return streflop_libm::__ilogbf(x);}
|
|
inline Simple copysign(Simple x) {return streflop_libm::__copysignf(x);}
|
|
#undef signbit
|
|
inline int signbit (Simple x) {return streflop_libm::__signbitf(x);}
|
|
inline Simple nextafter(Simple x, Simple y) {return streflop_libm::__nextafterf(x,y);}
|
|
|
|
inline Simple expm1(Simple x) {return streflop_libm::__expm1f(x);}
|
|
inline Simple log1p(Simple x) {return streflop_libm::__log1pf(x);}
|
|
inline Simple erf(Simple x) {return streflop_libm::__erff(x);}
|
|
inline Simple j0(Simple x) {return streflop_libm::__ieee754_j0f(x);}
|
|
inline Simple j1(Simple x) {return streflop_libm::__ieee754_j1f(x);}
|
|
inline Simple jn(int n, Simple x) {return streflop_libm::__ieee754_jnf(n,x);}
|
|
inline Simple y0(Simple x) {return streflop_libm::__ieee754_y0f(x);}
|
|
inline Simple y1(Simple x) {return streflop_libm::__ieee754_y1f(x);}
|
|
inline Simple yn(int n, Simple x) {return streflop_libm::__ieee754_ynf(n,x);}
|
|
inline Simple scalbn(Simple x, int n) {return streflop_libm::__scalbnf(x,n);}
|
|
inline Simple scalbln(Simple x, long int n) {return streflop_libm::__scalblnf(x,n);}
|
|
|
|
#undef fpclassify
|
|
inline int fpclassify(Simple x) {return streflop_libm::__fpclassifyf(x);}
|
|
#undef isnan
|
|
inline int isnan(Simple x) {return streflop_libm::__isnanf(x);}
|
|
#undef isinf
|
|
inline int isinf(Simple x) {return streflop_libm::__isinff(x);}
|
|
#undef isfinite
|
|
inline int isfinite(Simple x) {return !(isnan(x) || isinf(x));}
|
|
|
|
// Stolen from math.h and inlined instead of macroized.
|
|
// Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
|
|
#undef isnormal
|
|
inline int isnormal(Simple x) {return fpclassify(x) == STREFLOP_FP_NORMAL;}
|
|
|
|
// Constants user may set
|
|
extern const Simple SimplePositiveInfinity;
|
|
extern const Simple SimpleNegativeInfinity;
|
|
// Non-signaling NaN used for returning such results
|
|
// Standard lets a large room for implementing different kinds of NaN
|
|
// These NaN can be used for custom purposes
|
|
// Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers!
|
|
// Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean.
|
|
extern const Simple SimpleNaN;
|
|
|
|
/** Generic C99 "macros" for unordered comparison
|
|
Defined as inlined for each type, thanks to C++ overloading
|
|
*/
|
|
#if defined isunordered
|
|
#undef isunordered
|
|
#endif // defined isunordered
|
|
inline bool isunordered(Simple x, Simple y) {
|
|
return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify(y) == STREFLOP_FP_NAN);
|
|
}
|
|
#if defined isgreater
|
|
#undef isgreater
|
|
#endif // defined isgreater
|
|
inline bool isgreater(Simple x, Simple y) {
|
|
return (!isunordered(x,y)) && (x > y);
|
|
}
|
|
#if defined isgreaterequal
|
|
#undef isgreaterequal
|
|
#endif // defined isgreaterequal
|
|
inline bool isgreaterequal(Simple x, Simple y) {
|
|
return (!isunordered(x,y)) && (x >= y);
|
|
}
|
|
#if defined isless
|
|
#undef isless
|
|
#endif // defined isless
|
|
inline bool isless(Simple x, Simple y) {
|
|
return (!isunordered(x,y)) && (x < y);
|
|
}
|
|
#if defined islessequal
|
|
#undef islessequal
|
|
#endif // defined islessequal
|
|
inline bool islessequal(Simple x, Simple y) {
|
|
return (!isunordered(x,y)) && (x <= y);
|
|
}
|
|
#if defined islessgreater
|
|
#undef islessgreater
|
|
#endif // defined islessgreater
|
|
inline bool islessgreater(Simple x, Simple y) {
|
|
return (!isunordered(x,y)) && ((x < y) || (x > y));
|
|
}
|
|
|
|
|
|
// Add xxxf alias to ease porting existing code to streflop
|
|
// Additionally, using xxxf(number) avoids potential confusion
|
|
|
|
inline Simple sqrtf(Simple x) {return sqrt(x);}
|
|
inline Simple cbrtf(Simple x) {return cbrt(x);}
|
|
inline Simple hypotf(Simple x, Simple y) {return hypot(x, y);}
|
|
|
|
inline Simple expf(Simple x) {return exp(x);}
|
|
inline Simple logf(Simple x) {return log(x);}
|
|
inline Simple log2f(Simple x) {return log2(x);}
|
|
inline Simple exp2f(Simple x) {return exp2(x);}
|
|
inline Simple log10f(Simple x) {return log10(x);}
|
|
inline Simple powf(Simple x, Simple y) {return pow(x, y);}
|
|
|
|
inline Simple sinf(Simple x) {return sin(x);}
|
|
inline Simple cosf(Simple x) {return cos(x);}
|
|
inline Simple tanf(Simple x) {return tan(x);}
|
|
inline Simple acosf(Simple x) {return acos(x);}
|
|
inline Simple asinf(Simple x) {return asin(x);}
|
|
inline Simple atanf(Simple x) {return atan(x);}
|
|
inline Simple atan2f(Simple x, Simple y) {return atan2(x, y);}
|
|
|
|
inline Simple coshf(Simple x) {return cosh(x);}
|
|
inline Simple sinhf(Simple x) {return sinh(x);}
|
|
inline Simple tanhf(Simple x) {return tanh(x);}
|
|
inline Simple acoshf(Simple x) {return acosh(x);}
|
|
inline Simple asinhf(Simple x) {return asinh(x);}
|
|
inline Simple atanhf(Simple x) {return atanh(x);}
|
|
|
|
inline Simple fabsf(Simple x) {return fabs(x);}
|
|
inline Simple floorf(Simple x) {return floor(x);}
|
|
inline Simple ceilf(Simple x) {return ceil(x);}
|
|
inline Simple truncf(Simple x) {return trunc(x);}
|
|
inline Simple fmodf(Simple x, Simple y) {return fmod(x,y);}
|
|
inline Simple remainderf(Simple x, Simple y) {return remainder(x,y);}
|
|
inline Simple remquof(Simple x, Simple y, int *quo) {return remquo(x, y, quo);}
|
|
inline Simple rintf(Simple x) {return rint(x);}
|
|
inline long int lrintf(Simple x) {return lrint(x);}
|
|
inline long long int llrintf(Simple x) {return llrint(x);}
|
|
inline Simple roundf(Simple x) {return round(x);}
|
|
inline long int lroundf(Simple x) {return lround(x);}
|
|
inline long long int llroundf(Simple x) {return llround(x);}
|
|
inline Simple nearbyintf(Simple x) {return nearbyint(x);}
|
|
|
|
inline Simple frexpf(Simple x, int *exp) {return frexp(x, exp);}
|
|
inline Simple ldexpf(Simple value, int exp) {return ldexp(value,exp);}
|
|
inline Simple logbf(Simple x) {return logb(x);}
|
|
inline int ilogbf(Simple x) {return ilogb(x);}
|
|
inline Simple copysignf(Simple x) {return copysign(x);}
|
|
inline int signbitf(Simple x) {return signbit(x);}
|
|
inline Simple nextafterf(Simple x, Simple y) {return nextafter(x, y);}
|
|
|
|
inline Simple expm1f(Simple x) {return expm1(x);}
|
|
inline Simple log1pf(Simple x) {return log1p(x);}
|
|
inline Simple erff(Simple x) {return erf(x);}
|
|
inline Simple j0f(Simple x) {return j0(x);}
|
|
inline Simple j1f(Simple x) {return j1(x);}
|
|
inline Simple jnf(int n, Simple x) {return jn(n, x);}
|
|
inline Simple y0f(Simple x) {return y0(x);}
|
|
inline Simple y1f(Simple x) {return y1(x);}
|
|
inline Simple ynf(int n, Simple x) {return yn(n, x);}
|
|
inline Simple scalbnf(Simple x, int n) {return scalbn(x, n);}
|
|
inline Simple scalblnf(Simple x, long int n) {return scalbln(x, n);}
|
|
|
|
inline int fpclassifyf(Simple x) {return fpclassify(x);}
|
|
inline int isnanf(Simple x) {return isnan(x);}
|
|
inline int isinff(Simple x) {return isinf(x);}
|
|
inline int isfinitef(Simple x) {return isfinite(x);}
|
|
inline int isnormalf(Simple x) {return isnormal(x);}
|
|
|
|
inline bool isunorderedf(Simple x, Simple y) {return isunordered(x, y);}
|
|
inline bool isgreaterf(Simple x, Simple y) {return isgreater(x, y);}
|
|
inline bool isgreaterequalf(Simple x, Simple y) {return isgreaterequalf(x, y);}
|
|
inline bool islessf(Simple x, Simple y) {return isless(x, y);}
|
|
inline bool islessequalf(Simple x, Simple y) {return islessequal(x, y);}
|
|
inline bool islessgreaterf(Simple x, Simple y) {return islessgreater(x, y);}
|
|
|
|
|
|
// Declare Double functions
|
|
// Simple and double are present in all configurations
|
|
|
|
inline Double sqrt(Double x) {return streflop_libm::__ieee754_sqrt(x);}
|
|
inline Double cbrt(Double x) {return streflop_libm::__cbrt(x);}
|
|
inline Double hypot(Double x, Double y) {return streflop_libm::__ieee754_hypot(x,y);}
|
|
|
|
inline Double exp(Double x) {return streflop_libm::__ieee754_exp(x);}
|
|
inline Double log(Double x) {return streflop_libm::__ieee754_log(x);}
|
|
inline Double log2(Double x) {return streflop_libm::__ieee754_log2(x);}
|
|
inline Double exp2(Double x) {return streflop_libm::__ieee754_exp2(x);}
|
|
inline Double log10(Double x) {return streflop_libm::__ieee754_log10(x);}
|
|
inline Double pow(Double x, Double y) {return streflop_libm::__ieee754_pow(x,y);}
|
|
|
|
inline Double sin(Double x) {return streflop_libm::__sin(x);}
|
|
inline Double cos(Double x) {return streflop_libm::__cos(x);}
|
|
inline Double tan(Double x) {return streflop_libm::tan(x);}
|
|
inline Double acos(Double x) {return streflop_libm::__ieee754_acos(x);}
|
|
inline Double asin(Double x) {return streflop_libm::__ieee754_asin(x);}
|
|
inline Double atan(Double x) {return streflop_libm::atan(x);}
|
|
inline Double atan2(Double x, Double y) {return streflop_libm::__ieee754_atan2(x,y);}
|
|
|
|
inline Double cosh(Double x) {return streflop_libm::__ieee754_cosh(x);}
|
|
inline Double sinh(Double x) {return streflop_libm::__ieee754_sinh(x);}
|
|
inline Double tanh(Double x) {return streflop_libm::__tanh(x);}
|
|
inline Double acosh(Double x) {return streflop_libm::__ieee754_acosh(x);}
|
|
inline Double asinh(Double x) {return streflop_libm::__asinh(x);}
|
|
inline Double atanh(Double x) {return streflop_libm::__ieee754_atanh(x);}
|
|
|
|
inline Double fabs(Double x) {return streflop_libm::__fabs(x);}
|
|
inline Double floor(Double x) {return streflop_libm::__floor(x);}
|
|
inline Double ceil(Double x) {return streflop_libm::__ceil(x);}
|
|
inline Double trunc(Double x) {return streflop_libm::__trunc(x);}
|
|
inline Double fmod(Double x, Double y) {return streflop_libm::__ieee754_fmod(x,y);}
|
|
inline Double remainder(Double x, Double y) {return streflop_libm::__ieee754_remainder(x,y);}
|
|
inline Double remquo(Double x, Double y, int *quo) {return streflop_libm::__remquo(x,y,quo);}
|
|
inline Double rint(Double x) {return streflop_libm::__rint(x);}
|
|
inline long int lrint(Double x) {return streflop_libm::__lrint(x);}
|
|
inline long long int llrint(Double x) {return streflop_libm::__llrint(x);}
|
|
inline Double round(Double x) {return streflop_libm::__round(x);}
|
|
inline long int lround(Double x) {return streflop_libm::__lround(x);}
|
|
inline long long int llround(Double x) {return streflop_libm::__llround(x);}
|
|
inline Double nearbyint(Double x) {return streflop_libm::__nearbyint(x);}
|
|
|
|
inline Double frexp(Double x, int *exp) {return streflop_libm::__frexp(x, exp);}
|
|
inline Double ldexp(Double value, int exp) {return streflop_libm::__ldexp(value,exp);}
|
|
inline Double logb(Double x) {return streflop_libm::__logb(x);}
|
|
inline int ilogb(Double x) {return streflop_libm::__ilogb(x);}
|
|
inline Double copysign(Double x) {return streflop_libm::__copysign(x);}
|
|
inline int signbit(Double x) {return streflop_libm::__signbit(x);}
|
|
inline Double nextafter(Double x, Double y) {return streflop_libm::__nextafter(x,y);}
|
|
|
|
inline Double expm1(Double x) {return streflop_libm::__expm1(x);}
|
|
inline Double log1p(Double x) {return streflop_libm::__log1p(x);}
|
|
inline Double erf(Double x) {return streflop_libm::__erf(x);}
|
|
inline Double j0(Double x) {return streflop_libm::__ieee754_j0(x);}
|
|
inline Double j1(Double x) {return streflop_libm::__ieee754_j1(x);}
|
|
inline Double jn(int n, Double x) {return streflop_libm::__ieee754_jn(n,x);}
|
|
inline Double y0(Double x) {return streflop_libm::__ieee754_y0(x);}
|
|
inline Double y1(Double x) {return streflop_libm::__ieee754_y1(x);}
|
|
inline Double yn(int n, Double x) {return streflop_libm::__ieee754_yn(n,x);}
|
|
inline Double scalbn(Double x, int n) {return streflop_libm::__scalbn(x,n);}
|
|
inline Double scalbln(Double x, long int n) {return streflop_libm::__scalbln(x,n);}
|
|
|
|
inline int fpclassify(Double x) {return streflop_libm::__fpclassify(x);}
|
|
inline int isnan(Double x) {return streflop_libm::__isnanl(x);}
|
|
inline int isinf(Double x) {return streflop_libm::__isinf(x);}
|
|
inline int isfinite(Double x) {return !(isnan(x) || isinf(x));}
|
|
|
|
// Stolen from math.h and inlined instead of macroized.
|
|
// Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
|
|
inline int isnormal(Double x) {return fpclassify(x) == STREFLOP_FP_NORMAL;}
|
|
|
|
// Constants user may set
|
|
extern const Double DoublePositiveInfinity;
|
|
extern const Double DoubleNegativeInfinity;
|
|
// Non-signaling NaN used for returning such results
|
|
// Standard lets a large room for implementing different kinds of NaN
|
|
// These NaN can be used for custom purposes
|
|
// Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers!
|
|
// Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean.
|
|
extern const Double DoubleNaN;
|
|
|
|
/** Generic C99 "macros" for unordered comparison
|
|
Defined as inlined for each type, thanks to C++ overloading
|
|
*/
|
|
inline bool isunordered(Double x, Double y) {
|
|
return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN);
|
|
}
|
|
inline bool isgreater(Double x, Double y) {
|
|
return (!isunordered(x,y)) && (x > y);
|
|
}
|
|
inline bool isgreaterequal(Double x, Double y) {
|
|
return (!isunordered(x,y)) && (x >= y);
|
|
}
|
|
inline bool isless(Double x, Double y) {
|
|
return (!isunordered(x,y)) && (x < y);
|
|
}
|
|
inline bool islessequal(Double x, Double y) {
|
|
return (!isunordered(x,y)) && (x <= y);
|
|
}
|
|
inline bool islessgreater(Double x, Double y) {
|
|
return (!isunordered(x,y)) && ((x < y) || (x > y));
|
|
}
|
|
|
|
// Extended are not always available
|
|
#ifdef Extended
|
|
|
|
inline Extended cbrt(Extended x) {return streflop_libm::__cbrtl(x);}
|
|
inline Extended hypot(Extended x, Extended y) {return streflop_libm::__ieee754_hypotl(x,y);}
|
|
|
|
|
|
// Missing from libm: temporarily switch to Double and execute the Double version,
|
|
// then switch back to Extended and return the result
|
|
inline Extended sqrt(Extended x) {streflop_init<Double>(); Double res = sqrt(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
|
|
inline Extended exp(Extended x) {streflop_init<Double>(); Double res = exp(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended log(Extended x) {streflop_init<Double>(); Double res = log(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended log2(Extended x) {streflop_init<Double>(); Double res = log2(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended exp2(Extended x) {streflop_init<Double>(); Double res = exp2(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended log10(Extended x) {streflop_init<Double>(); Double res = log10(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended pow(Extended x, Extended y) {streflop_init<Double>(); Double res = pow(Double(x), Double(y)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended sin(Extended x) {streflop_init<Double>(); Double res = sin(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended cos(Extended x) {streflop_init<Double>(); Double res = cos(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended tan(Extended x) {streflop_init<Double>(); Double res = tan(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended acos(Extended x) {streflop_init<Double>(); Double res = acos(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended asin(Extended x) {streflop_init<Double>(); Double res = asin(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended atan(Extended x) {streflop_init<Double>(); Double res = atan(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended atan2(Extended x, Extended y) {streflop_init<Double>(); Double res = atan2(Double(x), Double(y)); streflop_init<Extended>(); return Extended(res);}
|
|
|
|
inline Extended cosh(Extended x) {streflop_init<Double>(); Double res = cosh(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended sinh(Extended x) {streflop_init<Double>(); Double res = sinh(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended tanh(Extended x) {streflop_init<Double>(); Double res = tanh(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended acosh(Extended x) {streflop_init<Double>(); Double res = acosh(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended asinh(Extended x) {streflop_init<Double>(); Double res = asinh(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended atanh(Extended x) {streflop_init<Double>(); Double res = atanh(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
|
|
|
|
inline Extended expm1(Extended x) {streflop_init<Double>(); Double res = expm1(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended log1p(Extended x) {streflop_init<Double>(); Double res = log1p(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended erf(Extended x) {streflop_init<Double>(); Double res = erf(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended j0(Extended x) {streflop_init<Double>(); Double res = j0(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended j1(Extended x) {streflop_init<Double>(); Double res = j1(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended jn(int n, Extended x) {streflop_init<Double>(); Double res = jn(n,Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended y0(Extended x) {streflop_init<Double>(); Double res = y0(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended y1(Extended x) {streflop_init<Double>(); Double res = y1(Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended yn(int n, Extended x) {streflop_init<Double>(); Double res = yn(n,Double(x)); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended scalbn(Extended x, int n) {streflop_init<Double>(); Double res = scalbn(Double(x),n); streflop_init<Extended>(); return Extended(res);}
|
|
inline Extended scalbln(Extended x, long int n) {streflop_init<Double>(); Double res = scalbln(Double(x),n); streflop_init<Extended>(); return Extended(res);}
|
|
|
|
|
|
|
|
inline Extended fabs(Extended x) {return streflop_libm::__fabsl(x);}
|
|
inline Extended floor(Extended x) {return streflop_libm::__floorl(x);}
|
|
inline Extended ceil(Extended x) {return streflop_libm::__ceill(x);}
|
|
inline Extended trunc(Extended x) {return streflop_libm::__truncl(x);}
|
|
inline Extended fmod(Extended x, Extended y) {return streflop_libm::__ieee754_fmodl(x,y);}
|
|
inline Extended remainder(Extended x, Extended y) {return streflop_libm::__ieee754_remainderl(x,y);}
|
|
inline Extended remquo(Extended x, Extended y, int *quo) {return streflop_libm::__remquol(x,y,quo);}
|
|
inline Extended rint(Extended x) {return streflop_libm::__rintl(x);}
|
|
inline long int lrint(Extended x) {return streflop_libm::__lrintl(x);}
|
|
inline long long int llrint(Extended x) {return streflop_libm::__llrintl(x);}
|
|
inline Extended round(Extended x) {return streflop_libm::__roundl(x);}
|
|
inline long int lround(Extended x) {return streflop_libm::__lroundl(x);}
|
|
inline long long int llround(Extended x) {return streflop_libm::__llroundl(x);}
|
|
inline Extended nearbyint(Extended x) {return streflop_libm::__nearbyintl(x);}
|
|
|
|
inline Extended frexp(Extended x, int *exp) {return streflop_libm::__frexpl(x,exp);}
|
|
inline Extended ldexp(Extended value, int exp) {return streflop_libm::__ldexpl(value,exp);}
|
|
inline Extended logb(Extended x) {return streflop_libm::__logbl(x);}
|
|
inline int ilogb(Extended x) {return streflop_libm::__ilogbl(x);}
|
|
inline Extended copysign(Extended x) {return streflop_libm::__copysignl(x);}
|
|
inline int signbit (Extended x) {return streflop_libm::__signbitl(x);}
|
|
inline Extended nextafter(Extended x, Extended y) {return streflop_libm::__nextafterl(x,y);}
|
|
|
|
inline int fpclassify(Extended x) {return streflop_libm::__fpclassifyl(x);}
|
|
inline int isnan(Extended x) {return streflop_libm::__isnanl(x);}
|
|
inline int isinf(Extended x) {return streflop_libm::__isinfl(x);}
|
|
inline int isfinite(Extended x) {return !(isnan(x) || isinf(x));}
|
|
|
|
// Stolen from math.h and inlined instead of macroized.
|
|
// Return nonzero value if X is neither zero, subnormal, Inf, nor NaN. */
|
|
inline int isnormal(Extended x) {return fpclassify(x) == STREFLOP_FP_NORMAL;}
|
|
|
|
// Constants user may set
|
|
extern const Extended ExtendedPositiveInfinity;
|
|
extern const Extended ExtendedNegativeInfinity;
|
|
// Non-signaling NaN used for returning such results
|
|
// Standard lets a large room for implementing different kinds of NaN
|
|
// These NaN can be used for custom purposes
|
|
// Threated as an integer, the bit pattern here may be incremented to get at least 2^20 different NaN custom numbers!
|
|
// Note that when switching the left-most bit to 1, you can get another bunch of negative NaNs, whatever this mean.
|
|
extern const Extended ExtendedNaN;
|
|
|
|
/** Generic C99 "macros" for unordered comparison
|
|
Defined as inlined for each type, thanks to C++ overloading
|
|
*/
|
|
inline bool isunordered(Extended x, Extended y) {
|
|
return (fpclassify(x) == STREFLOP_FP_NAN) || (fpclassify (y) == STREFLOP_FP_NAN);
|
|
}
|
|
inline bool isgreater(Extended x, Extended y) {
|
|
return (!isunordered(x,y)) && (x > y);
|
|
}
|
|
inline bool isgreaterequal(Extended x, Extended y) {
|
|
return (!isunordered(x,y)) && (x >= y);
|
|
}
|
|
inline bool isless(Extended x, Extended y) {
|
|
return (!isunordered(x,y)) && (x < y);
|
|
}
|
|
inline bool islessequal(Extended x, Extended y) {
|
|
return (!isunordered(x,y)) && (x <= y);
|
|
}
|
|
inline bool islessgreater(Extended x, Extended y) {
|
|
return (!isunordered(x,y)) && ((x < y) || (x > y));
|
|
}
|
|
|
|
|
|
// Add xxxl alias to ease porting existing code to streflop
|
|
// Additionally, using xxxl(number) avoids potential confusion
|
|
|
|
inline Extended sqrtl(Extended x) {return sqrt(x);}
|
|
inline Extended cbrtl(Extended x) {return cbrt(x);}
|
|
inline Extended hypotl(Extended x, Extended y) {return hypot(x, y);}
|
|
|
|
inline Extended expl(Extended x) {return exp(x);}
|
|
inline Extended logl(Extended x) {return log(x);}
|
|
inline Extended log2l(Extended x) {return log2(x);}
|
|
inline Extended exp2l(Extended x) {return exp2(x);}
|
|
inline Extended log10l(Extended x) {return log10(x);}
|
|
inline Extended powl(Extended x, Extended y) {return pow(x, y);}
|
|
|
|
inline Extended sinl(Extended x) {return sin(x);}
|
|
inline Extended cosl(Extended x) {return cos(x);}
|
|
inline Extended tanl(Extended x) {return tan(x);}
|
|
inline Extended acosl(Extended x) {return acos(x);}
|
|
inline Extended asinl(Extended x) {return asin(x);}
|
|
inline Extended atanl(Extended x) {return atan(x);}
|
|
inline Extended atan2l(Extended x, Extended y) {return atan2(x, y);}
|
|
|
|
inline Extended coshl(Extended x) {return cosh(x);}
|
|
inline Extended sinhl(Extended x) {return sinh(x);}
|
|
inline Extended tanhl(Extended x) {return tanh(x);}
|
|
inline Extended acoshl(Extended x) {return acosh(x);}
|
|
inline Extended asinhl(Extended x) {return asinh(x);}
|
|
inline Extended atanhl(Extended x) {return atanh(x);}
|
|
|
|
inline Extended fabsl(Extended x) {return fabs(x);}
|
|
inline Extended floorl(Extended x) {return floor(x);}
|
|
inline Extended ceill(Extended x) {return ceil(x);}
|
|
inline Extended truncl(Extended x) {return trunc(x);}
|
|
inline Extended fmodl(Extended x, Extended y) {return fmod(x,y);}
|
|
inline Extended remainderl(Extended x, Extended y) {return remainder(x,y);}
|
|
inline Extended remquol(Extended x, Extended y, int *quo) {return remquo(x, y, quo);}
|
|
inline Extended rintl(Extended x) {return rint(x);}
|
|
inline long int lrintl(Extended x) {return lrint(x);}
|
|
inline long long int llrintl(Extended x) {return llrint(x);}
|
|
inline Extended roundl(Extended x) {return round(x);}
|
|
inline long int lroundl(Extended x) {return lround(x);}
|
|
inline long long int llroundl(Extended x) {return llround(x);}
|
|
inline Extended nearbyintl(Extended x) {return nearbyint(x);}
|
|
|
|
inline Extended frexpl(Extended x, int *exp) {return frexp(x, exp);}
|
|
inline Extended ldexpl(Extended value, int exp) {return ldexp(value,exp);}
|
|
inline Extended logbl(Extended x) {return logb(x);}
|
|
inline int ilogbl(Extended x) {return ilogb(x);}
|
|
inline Extended copysignl(Extended x) {return copysign(x);}
|
|
inline int signbitl(Extended x) {return signbit(x);}
|
|
inline Extended nextafterl(Extended x, Extended y) {return nextafter(x, y);}
|
|
|
|
inline Extended expm1l(Extended x) {return expm1(x);}
|
|
inline Extended log1pl(Extended x) {return log1p(x);}
|
|
inline Extended erfl(Extended x) {return erf(x);}
|
|
inline Extended j0l(Extended x) {return j0(x);}
|
|
inline Extended j1l(Extended x) {return j1(x);}
|
|
inline Extended jnl(int n, Extended x) {return jn(n, x);}
|
|
inline Extended y0l(Extended x) {return y0(x);}
|
|
inline Extended y1l(Extended x) {return y1(x);}
|
|
inline Extended ynl(int n, Extended x) {return yn(n, x);}
|
|
inline Extended scalbnl(Extended x, int n) {return scalbn(x, n);}
|
|
inline Extended scalblnl(Extended x, long int n) {return scalbln(x, n);}
|
|
|
|
inline int fpclassifyl(Extended x) {return fpclassify(x);}
|
|
inline int isnanl(Extended x) {return isnan(x);}
|
|
inline int isinfl(Extended x) {return isinf(x);}
|
|
inline int isfinitel(Extended x) {return isfinite(x);}
|
|
inline int isnormall(Extended x) {return isnormal(x);}
|
|
|
|
inline bool isunorderedl(Extended x, Extended y) {return isunordered(x, y);}
|
|
inline bool isgreaterl(Extended x, Extended y) {return isgreater(x, y);}
|
|
inline bool isgreaterequall(Extended x, Extended y) {return isgreaterequall(x, y);}
|
|
inline bool islessl(Extended x, Extended y) {return isless(x, y);}
|
|
inline bool islessequall(Extended x, Extended y) {return islessequal(x, y);}
|
|
inline bool islessgreaterl(Extended x, Extended y) {return islessgreater(x, y);}
|
|
|
|
|
|
#endif // Extended
|
|
|
|
} // namespace streflop
|
|
|
|
#endif // STREFLOP_MATH_H
|