/* The header math.h declares two types and many common mathematical operations * and defines several macros. */ #ifndef _MATH_ #define _MATH_ #pragma CIVL ACSL /* Types */ #ifndef FLT_EVAL_METHOD #define FLT_EVAL_METHOD 0 #endif #if (FLT_EVAL_METHOD == 0) #define float_t float // floating-point type at least //as wide as 'float' used to evaluate //'float' expression. #define double_t double // floating-point type at least //as wide as 'double' used to evaluate //'double' expression. #elif (FLT_EVAL_METHOD == 1) #define float_t double #define double_t double #elif (FLT_EVAL_METHOD == 2) #define float_t long double #define double_t long double #else // Implementation defined. #define float_t float #define double_t double #endif /* Macros */ //In CIVL implementation, they better be abstract functions. //TODO: Make PI an abstract function with assumptions. //3.14 < PI < 3.15 #define M_E 2.7182818284590452354 #define M_LOG2E 1.4426950408889634074 #define M_LOG10E 0.43429448190325182765 #define M_LN2 0.69314718055994530942 #define M_LN10 2.30258509299404568402 #define M_PI 3.14159265358979323846 #define M_PI_2 M_PI/2.0 //1.57079632679489661923 #define M_PI_4 0.78539816339744830962 #define M_1_PI 0.31830988618379067154 #define M_2_PI 0.63661977236758134308 #define M_2_SQRTPI 1.12837916709551257390 #define M_SQRT2 1.41421356237309504880 #define M_SQRT1_2 0.70710678118654752440 #define HUGE_VAL 3.40282347e+38F #define HUGE_VALF 3.40282347e+38F #define HUGE_VALL 3.40282347e+38F #define INFINITY (1/0) #define NAN sqrt(-1) typedef enum { FP_INFINITE, FP_NAN, FP_ZERO, FP_NORMAL, FP_SUBNORMAL }number_classification; #define FP_FAST_FMA 1 #define FP_FAST_FMAF 1 #define FP_FAST_FMAL 1 typedef enum { MATH_ERRNO = 2, MATH_ERREXCEPT = 3 }math_errhandling; // Macro functions #define fpclassify(x) \ ((sizeof(x) == sizeof(float)) ? __fpclassifyf(x) : \ (sizeof(x) == sizeof(double)) ? __fpclassifyd(x) : \ __fpclassifyl(x)) #define isfinite(x) \ ((sizeof(x) == sizeof(float)) ? __isfinitef(x) : \ (sizeof(x) == sizeof(double)) ? __isfinited(x) : \ __isfinitel(x)) #define isinf(x) \ ((sizeof(x) == sizeof(float)) ? __isinff(x) : \ (sizeof(x) == sizeof(double)) ? __isinfd(x) : \ __isinfl(x)) #define isnan(x) \ ((sizeof(x) == sizeof(float)) ? __isnanf(x) : \ (sizeof(x) == sizeof(double)) ? __isnand(x) : \ __isnanl(x)) #define isnormal(x) \ ((sizeof(x) == sizeof(float)) ? __isnormalf(x) : \ (sizeof(x) == sizeof(double)) ? __isnormald(x) : \ __isnormall(x)) #define signbit(x) \ ((sizeof(x) == sizeof(float)) ? __signbitf(x) : \ (sizeof(x) == sizeof(double)) ? __signbitd(x) : \ __signbitl(x)) int __fpclassifyf (float x); int __fpclassifyd (double x); int __fpclassifyl (long double x); int __isfinitef (float x); int __isfinited (double x); int __isfinitel (long double x); int __isinff (float x); int __isinfd (double x); int __isinfl (long double x); int __isnanf (float x); int __isnand (double x); int __isnanl (long double x); int __isnormalf (float x); int __isnormald (double x); int __isnormall (long double x); int __signbitf (float x); int __signbitd (double x); int __signbitl (long double x); //trigonomatric functions /*@ pure; @*/ double acos(double x); /*@ pure; @*/ float acosf(float x); /*@ pure; @*/ long double acosl(long double x); /*@ pure; @*/ double asin(double x); /*@ pure; @*/ float asinf(float x); /*@ pure; @*/ long double asinl(long double x); /*@ pure; @*/ double atan(double x); /*@ pure; @*/ float atanf(float x); /*@ pure; @*/ long double atanl(long double x); /*@ pure; @*/ double atan2(double y, double x); /*@ pure; @*/ float atan2f(float y, float x); /*@ pure; @*/ long double atan2l(long double y, long double x); /*@ pure; @*/ double cos(double x); /*@ pure; @*/ float cosf(float x); /*@ pure; @*/ long double cosl(long double x); /*@ pure; @*/ double sin(double x); /*@ pure; @*/ float sinf(float x); /*@ pure; @*/ long double sinl(long double x); /*@ pure; @*/ double tan(double x); /*@ pure; @*/ float tanf(float x); /*@ pure; @*/ long double tanl(long double x); //hyperbolic functions /*@ pure; @*/ double acosh(double x); /*@ pure; @*/ float acoshf(float x); /*@ pure; @*/ long double acoshl(long double x); /*@ pure; @*/ double asinh(double x); /*@ pure; @*/ float asinhf(float x); /*@ pure; @*/ long double asinhl(long double x); /*@ pure; @*/ double atan(double x); /*@ pure; @*/ float atanf(float x); /*@ pure; @*/ long double atanl(long double x); /*@ pure; @*/ double atanh(double x); /*@ pure; @*/ float atanhf(float x); /*@ pure; @*/ long double atanhl(long double x); /*@ pure; @*/ double cosh(double x); /*@ pure; @*/ float coshf(float x); /*@ pure; @*/ long double coshl(long double x); /*@ pure; @*/ double sinh(double x); /*@ pure; @*/ float sinhf(float x); /*@ pure; @*/ long double sinhl(long double x); /*@ pure; @*/ double tanh(double x); /*@ pure; @*/ float tanhf(float x); /*@ pure; @*/ long double tanhl(long double x); //exponential and logistic functions /*@ pure; @*/ double exp(double x); /*@ pure; @*/ float expf(float x); /*@ pure; @*/ long double expl(long double x); /*@ pure; @*/ double exp2(double x); /*@ pure; @*/ float exp2f(float x); /*@ pure; @*/ long double exp2l(long double x); /*@ pure; @*/ double expm1(double x); /*@ pure; @*/ float expm1f(float x); /*@ pure; @*/ long double expm1l(long double x); /*@ pure; @*/ double frexp(double value, int *exp); /*@ pure; @*/ float frexpf(float value, int *exp); /*@ pure; @*/ long double frexpl(long double value, int *exp); /*@ pure; @*/ int ilogb(double x); /*@ pure; @*/ int ilogbf(float x); /*@ pure; @*/ int ilogbl(long double x); /*@ pure; @*/ double ldexp(double x, int exp); /*@ pure; @*/ float ldexpf(float x, int exp); /*@ pure; @*/ long double ldexpl(long double x, int exp); /*@ pure; @*/ double log(double x); /*@ pure; @*/ float logf(float x); /*@ pure; @*/ long double logl(long double x); /*@ pure; @*/ double log10(double x); /*@ pure; @*/ float log10f(float x); /*@ pure; @*/ long double log10l(long double x); /*@ pure; @*/ double log1p(double x); /*@ pure; @*/ float log1pf(float x); /*@ pure; @*/ long double log1pl(long double x); /*@ pure; @*/ double log2(double x); /*@ pure; @*/ float log2f(float x); /*@ pure; @*/ long double log2l(long double x); /*@ pure; @*/ double logb(double x); /*@ pure; @*/ float logbf(float x); /*@ pure; @*/ long double logbl(long double x); /*@ pure; @*/ double modf(double value, double * iptr); /*@ pure; @*/ float modff(float value, float * iptr); /*@ pure; @*/ long double modfl(long double value, long double * iptr); /*@ pure; @*/ double scalbn(double x, int n); /*@ pure; @*/ float scalbnf(float x, int n); /*@ pure; @*/ long double scalbnl(long double x, int n); /*@ pure; @*/ double scalbln(double x, int n); /*@ pure; @*/ float scalblnf(float x, int n); /*@ pure; @*/ long double scalblnl(long double x, int n); //power and absolute-value functions /*@ pure; @*/ double cbrt(double x); /*@ pure; @*/ float cbrtf(float x); /*@ pure; @*/ long double cbrtl(long double x); /*@ pure; @*/ double fabs(double x); /*@ pure; @*/ float fabsf(float x); /*@ pure; @*/ long double fabsl(long double x); /*@ pure; @*/ double hypot(double x, double y); /*@ pure; @*/ float hypotf(float x, float y); /*@ pure; @*/ long double hypotl(long double x, long double y); /*@ pure; @*/ double pow(double x, double y); /*@ pure; @*/ float powf(float x, float y); /*@ pure; @*/ long double powl(long double x, long double y); /*@ pure; @*/ double sqrt(double x); /*@ pure; @*/ float sqrtf(float x); /*@ pure; @*/ long double sqrtl(long double x); //error and gamma functions /*@ pure; @*/ double erf(double x); /*@ pure; @*/ float erff(float x); /*@ pure; @*/ long double erfl(long double x); /*@ pure; @*/ double erfc(double x); /*@ pure; @*/ float erfcf(float x); /*@ pure; @*/ long double erfcl(long double x); /*@ pure; @*/ double lgamma(double x); /*@ pure; @*/ float lgammaf(float x); /*@ pure; @*/ long double lgammal(long double x); /*@ pure; @*/ double tgamma(double x); /*@ pure; @*/ float tgammaf(float x); /*@ pure; @*/ long double tgammal(long double x); //nearest integer functions /*@ pure; @ executes_when \true; @*/ $system double ceil(double x); /*@ pure; @ executes_when \true; @*/ $system float ceilf(float x); /*@ pure; @ executes_when \true; @*/ $system long double ceill(long double x); /*@ pure; @ executes_when \true; @*/ $system double floor(double x); /*@ pure; @ executes_when \true; @*/ $system float floorf(float x); /*@ pure; @ executes_when \true; @*/ $system long double floorl(long double x); /*@ pure; @*/ double nearbyint(double x); /*@ pure; @*/ float nearbyintf(float x); /*@ pure; @*/ long double nearbyintl(long double x); /*@ pure; @*/ double rint(double x); /*@ pure; @*/ float rintf(float x); /*@ pure; @*/ long double rintl(long double x); /*@ pure; @*/ long int lrint(double x); /*@ pure; @*/ long int lrintf(float x); /*@ pure; @*/ long int lrintl(long double x); /*@ pure; @*/ long long int llrint(double x); /*@ pure; @*/ long long int llrintf(float x); /*@ pure; @*/ long long int llrintl(long double x); /*@ pure; @*/ double round(double x); /*@ pure; @*/ float roundf(float x); /*@ pure; @*/ long double roundl(long double x); /*@ pure; @*/ long int lround(double x); /*@ pure; @*/ long int lroundf(float x); /*@ pure; @*/ long int lroundl(long double x); /*@ pure; @*/ long long int llround(double x); /*@ pure; @*/ long long int llroundf(float x); /*@ pure; @*/ long long int llroundl(long double x); /*@ pure; @*/ double trunc(double x); /*@ pure; @*/ float truncf(float x); /*@ pure; @*/ long double truncl(long double x); //remainder /*@ pure; @*/ double fmod(double x, double y); /*@ pure; @*/ float fmodf(float x, float y); /*@ pure; @*/ long double fmodl(long double x, long double y); /*@ pure; @*/ double remainder(double x, double y); /*@ pure; @*/ float remainderf(float x, float y); /*@ pure; @*/ long double remainderl(long double x, long double y); /*@ pure; @*/ double remquo(double x, double y, int *quo); /*@ pure; @*/ float remquof(float x, float y, int *quo); /*@ pure; @*/ long double remquol(long double x, long double y, int *quo); //Manipulation functions /*@ pure; @*/ double copysign(double x, double y); /*@ pure; @*/ float copysignf(float x, float y); /*@ pure; @*/ long double copysignl(long double x, long double y); /*@ pure; @*/ double nan(const char *tagp); /*@ pure; @*/ float nanf(const char *tagp); /*@ pure; @*/ long double nanl(const char *tagp); /*@ pure; @*/ double nextafter(double x, double y); /*@ pure; @*/ float nextafterf(float x, float y); /*@ pure; @*/ long double nextafterl(long double x, long double y); /*@ pure; @*/ double nexttoward(double x, long double y); /*@ pure; @*/ float nexttowardf(float x, long double y); /*@ pure; @*/ long double nexttowardl(long double x, long double y); // Maximum, minimum and positive difference functions /*@ pure; @*/ double fdim(double x, double y); /*@ pure; @*/ float fdimf(float x, float y); /*@ pure; @*/ long double fdiml(long double x, long double y); /*@ pure; @*/ double fmax(double x, double y); /*@ pure; @*/ float fmaxf(float x, float y); /*@ pure; @*/ long double fmaxl(long double x, long double y); /*@ pure; @*/ double fmin(double x, double y); /*@ pure; @*/ float fminf(float x, float y); /*@ pure; @*/ long double fminl(long double x, long double y); /*@ pure; @*/ double fma(double x, double y, double z); /*@ pure; @*/ float fmaf(float x, float y, float z); /*@ pure; @*/ long double fmal(long double x, long double y, long double z); // Comparison macros: #define isgreater(X,Y) ((X)>(Y)) #define isgreaterequal(X,Y) ((X)>=(Y)) #define isless(X,Y) ((X)<(Y)) #define islessequal(X,Y) ((X)<=(Y)) #define islessgreater(X,Y) ((X)<(Y))||((X)>(Y)) #define isunordered(X,Y) (X>Y)?1:0 #endif