
#ifndef __MATH_H
#define __MATH_H 1

#define HUGE_VAL        1e500

#if __STDC_VERSION__>=199901L
#define HUGE_VALF       1e500
#define HUGE_VALF       1e500


typedef float float_t;
typedef double double_t;

#define INFINITY 1e1000

/* #define NAN */

#define FP_INFINITE    1
#define FP_NAN         2
#define FP_NORMAL      3
#define FP_SUBNORMAL   4
#define FP_ZERO        5

/* #define FP_FAST_FMA */
/* #define FP_FAST_FMAF */
/* #define FP_FAST_FMAL */

#define FP_ILOGB0 0
#define FP_ILOGBNAN INT_MIN

#define MATH_ERRNO 1
#define MATH_ERREXCEPT 2
#define math_errhandling 0

#define fpclassify(x) FP_NORMAL
#ifdef __IEEE__
extern int isinf(double);
extern int isnan(double);
extern int isfinite(double);
extern int isnormal(double);
#else
#define isinf(x) 0
#define isnan(x) 0
#define isfinite(x) 1
#define isnormal(x) 1
#endif
#define signbit(x) (x<0)
#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))
#define isunordered(x,y) 0

#endif

/*
  Several of these functions may be well-suited to
  inline-assembly.
*/

double sin(double);
double cos(double);
double tan(double);
double sinh(double);
double cosh(double);
double tanh(double);
double asin(double);
double acos(double);
double atan(double);

double exp(double);
double log(double);
double log10(double);
double pow(double,double);
double sqrt(double);
double ceil(double);
double floor(double);
double fabs(double);
double atan2(double,double);
double ldexp(double,int);
double frexp(double,int *);
double modf(double,double *);
double fmod(double,double);


#if __STDC_VERSION__>=199901L



double asinh(double);
double acosh(double);
double atanh(double);
double expm1(double);
double exp2(double);
int ilogb(double);
double log1p(double);
double log2(double);
double logb(double);
double scalbn(double,int);
double scalbln(double,long int);
double cbrt(double);
double hypot(double,double);
double erf(double);
double erfc(double);
double lgamma(double);
double tgamma(double);
double nearbyint(double);
double rint(double);
long int lrint(double);
long long int llrint(double);
double round(double);
long int lround(double);
long long int llround(double);
double trunc(double);
double remainder(double,double);
double remquo(double,double,int*);
double copysign(double,double);
double nan(const char*);
double nextafter(double,double);
double nexttoward(double,long double);
double fdim(double,double);
double fmax(double,double);
double fmin(double,double);
double fma(double,double,double);


float sinf(float);
float cosf(float);
float tanf(float);
float sinhf(float);
float coshf(float);
float tanhf(float);
float asinhf(float);
float acoshf(float);
float atanhf(float);
float asinf(float);
float acosf(float);
float atanf(float);
float expf(float);
float expm1f(float);
float exp2f(float);
float logf(float);
float log10f(float);
float powf(float,float);
float sqrtf(float);
float ceilf(float);
float floorf(float);
float fabsf(float);
float atan2f(float,float);
float ldexpf(float,int);
float frexpf(float,int *);
float modff(float,float *);
float fmodf(float,float);
int ilogbf(float);
float log1pf(float);
float log2f(float);
float logbf(float);
float scalbnf(float,int);
float scalblnf(float,long int);
float cbrtf(float);
float hypotf(float,float);
float erff(float);
float erfcf(float);
float lgammaf(float);
float tgammaf(float);
float nearbyintf(float);
float rintf(float);
long int lrintf(float);
long long int llrintf(float);
float roundf(float);
long int lroundf(float);
long long int llroundf(float);
float truncf(float);
float remainderf(float,float);
float remquof(float,float,int*);
float copysignf(float,float);
float nanf(const char*);
float nextafterf(float,float);
float nexttowardf(float,long double);
float fdimf(float,float);
float fmaxf(float,float);
float fminf(float,float);
float fmaf(float,float,float);

long double sinl(long double);
long double cosl(long double);
long double tanl(long double);
long double sinhl(long double);
long double coshl(long double);
long double tanhl(long double);
long double asinhl(long double);
long double acoshl(long double);
long double atanhl(long double);
long double asinl(long double);
long double acosl(long double);
long double atanl(long double);
long double expl(long double);
long double expm1l(long double);
long double exp2l(long double);
long double logl(long double);
long double log10l(long double);
long double powl(long double,long double);
long double sqrtl(long double);
long double ceill(long double);
long double floorl(long double);
long double fabsl(long double);
long double atan2l(long double,long double);
long double ldexpl(long double,int);
long double frexpl(long double,int *);
long double modfl(long double,long double *);
long double fmodl(long double,long double);
int ilogbl(long double);
long double log1pl(long double);
long double log2l(long double);
long double logbl(long double);
long double scalbnl(long double,int);
long double scalblnl(long double,long int);
long double cbrtl(long double);
long double hypotl(long double,long double);
long double erfl(long double);
long double erfcl(long double);
long double lgammal(long double);
long double tgammal(long double);
long double nearbyintl(long double);
long double rintl(long double);
long int lrintl(long double);
long long int llrintl(long double);
long double roundl(long double);
long int lroundl(long double);
long long int llroundl(long double);
long double truncl(long double);
long double remainderl(long double,long double);
long double remquol(long double,long double,int*);
long double copysignl(long double,long double);
long double nanl(const char*);
long double nextafterl(long double,long double);
long double nexttowardl(long double,long double);
long double fdiml(long double,long double);
long double fmaxl(long double,long double);
long double fminl(long double,long double);
long double fmal(long double,long double,long double);

#if 0 /* activate if float==double? */
#define sinf(x) sin(x)
#define cosf(x) cos(x)
#define tanf(x) tan(x)
#define sinhf(x) sinh(x)
#define coshf(x) cosh(x)
#define tanhf(x) tanh(x)
#define asinhf(x) asinh(x)
#define acoshf(x) acosh(x)
#define atanhf(x) atanh(x)
#define asinf(x) asin(x)
#define acosf(x) acos(x)
#define atanf(x) atan(x)
#define expf(x) exp(x)
#define expm1f(x) expm1(x)
#define exp2f(x) exp2(x)
#define logf(x) log(x)
#define log10f(x) log10(x)
#define powf(x,y) pow(x,y)
#define sqrtf(x) sqrt(x)
#define ceilf(x) ceif(x)
#define floorf(x) floor(x)
#define fabsf(x) fabs(x)
#define atan2f(x,y) atan2(x,y)
#define ldexpf(x,y) ldexp(x,y)
#define frexpf(x,y) frexp(x,y)
#define modff(x,y) modf(x,y)
#define fmodf(x,y) fmod(x,y)
#define ilogbf(x) ilogb(x)
#define log1pf(x) log1p(x)
#define log2f(x) log2(x)
#define logbf(x) logb(x)
#define scalbnf(x,y) scalbn(x,y)
#define scalblnf(x,y) scalbln(x,y)
#define cbrtf(x) cbrt(x)
#define hypotf(x,y) hypot(x,y)
#define erff(x) erf(x)
#define erfcf(x) erfc(x)
#define lgammaf(x) lgamma(x)
#define tgammaf(x) tgamma(x)
#define nearbyintf(x) nearbyint(x)
#define rintf(x) rint(x)
#define lrintf(x) lrint(x)
#define llrintf(x) llrint(x)
#define roundf(x) round(x)
#define lroundf(x) lround(x)
#define llroundf(x) llround(x)
#define truncf(x) trunc(x)
#define remainderf(x,y) remainder(x,y)
#define remquof(x,y,z) remquo(x,y,z)
#define copysignf(x,y) copysign(x,y)
#define nanf(x) nan(x)
#define nextafterf(x,y) nextafter(x,y)
#define nexttowardf(x,y) nexttoward(x,y)
#define fdimf(x,y) fdim(x,y)
#define fmaxf(x,y) fmax(x,y)
#define fminf(x,y) fmin(x,y)
#define fmaf(x,y,z) fma(x,y,z)
#endif

#if 0 /* activate if long double==double? */
#define sinl(x) sin(x)
#define cosl(x) cos(x)
#define tanl(x) tan(x)
#define sinhl(x) sinh(x)
#define coshl(x) cosh(x)
#define tanhl(x) tanh(x)
#define asinhl(x) asinh(x)
#define acoshl(x) acosh(x)
#define atanhl(x) atanh(x)
#define asinl(x) asin(x)
#define acosl(x) acos(x)
#define atanl(x) atan(x)
#define expl(x) exp(x)
#define expm1l(x) expm1(x)
#define exp2l(x) exp2(x)
#define logl(x) log(x)
#define log10l(x) log10(x)
#define powl(x,y) pow(x,y)
#define sqrtl(x) sqrt(x)
#define ceill(x) ceil(x)
#define floorl(x) floor(x)
#define fabsl(x) fabs(x)
#define atan2l(x,y) atan2(x,y)
#define ldexpl(x,y) ldexp(x,y)
#define frexpl(x,y) frexp(x,y)
#define modfl(x,y) modf(x,y)
#define fmodl(x,y) fmod(x,y)
#define ilogbl(x) ilogb(x)
#define log1pl(x) log1p(x)
#define log2l(x) log2(x)
#define logbl(x) logb(x)
#define scalbnl(x,y) scalbn(x,y)
#define scalblnl(x,y) scalbln(x,y)
#define cbrtl(x) cbrt(x)
#define hypotl(x,y) hypot(x,y)
#define erfl(x) erf(x)
#define erfcl(x) erfc(x)
#define lgammal(x) lgamma(x)
#define tgammal(x) tgamma(x)
#define nearbyintl(x) nearbyint(x)
#define rintl(x) rint(x)
#define lrintl(x) lrint(x)
#define llrintl(x) llrint(x)
#define roundl(x) round(x)
#define lroundl(x) lround(x)
#define llroundl(x) llround(x)
#define truncl(x) trunc(x)
#define remainderl(x,y) remainder(x,y)
#define remquol(x,y,z) remquo(x,y,z)
#define copysignl(x,y) copysign(x,y)
#define nanl(x) nan(x)
#define nextafterl(x,y) nextafter(x,y)
#define nexttowardl(x,y) nexttoward(x,y)
#define fdiml(x,y) fdim(x,y)
#define fmaxl(x,y) fmax(x,y)
#define fminl(x,y) fmin(x,y)
#define fmal(x,y,z) fma(x,y,z)
#endif

#if 0 /* check which macros are efficient */
#define expm1(x) (exp(x)-1)
#define exp2(x) (exp((x)*0.693147180559945286227)
#define scalbn(x,y) ldexp((x),(y))
#define scalbln(x,y) ldexp((x),(int)(y))
#define cbrt(x) pow((x),0.3333333333333333)
#define nearbyint(x) round(x)
#define rint(x) round(x)
#define lrint(x) ((long)rint(x))
#define llrint(x) ((long long)rint(x))
#define lround(x) ((long)rint(x))
#define llround(x) ((long long)rint(x))
#define fma(x,y,z) ((x)*(y)+(z))
#endif


#endif /* C99 */

#endif /* MATH_H */
