#ifndef CMATH_H
#define CMATH_H

#ifdef __cplusplus
extern "C" {
#endif

inline long double fabsl(long double x) {
    return __fabs((double)x);
}

double acos(double);
double asin(double);
double atan(double);
double atan2(double, double);
double ceil(double);
double floor(double);
double frexp(double, int*);
double ldexp(double, int);
double sqrt(double);

double pow(double, double);

double log(double);
double log10(double);

double fmod(double, double);

double sin(double x);
double cos(double x);
double tan(double x);

double __ieee754_acos(double);
double __ieee754_fmod(double, double);
double __ieee754_log(double);
double __ieee754_log10(double);
double __ieee754_pow(double, double);
double __ieee754_sqrt(double);
double __ieee754_atan2(double, double);
double __ieee754_asin(double);

double scalbn(double, int);

double __kernel_sin(double, double, int);
double __kernel_cos(double, double);
double __kernel_tan(double, double, int);

int __ieee754_rem_pio2(double, double*);

#ifdef __MWERKS__
int __float_huge[];
int __float_nan[];
int __float_max[];
int __double_huge[];
int __float_epsilon[];

#define FLT_MAX (*(float*)__float_max)
#define INFINITY (*(float*)__float_huge)
#define NAN (*(float*)__float_nan)
#define HUGE_VAL (*(double*)__double_huge)
#endif

#define FLT_EPSILON 1.1920929e-7f

#define M_PI 3.14159265358979323846f
#define M_SQRT3 1.73205f

#define FP_SNAN 0
#define FP_QNAN 1
#define FP_INFINITE 2
#define FP_ZERO 3
#define FP_NORMAL 4
#define FP_SUBNORMAL 5

#define FP_NAN FP_QNAN

#define __HI(x) *(int*)&x
#define __LO(x) *(1 + (int*)&x)
#define __HIp(x) *(int*)x
#define __LOp(x) *(1 + (int*)x)

#ifdef __cplusplus
extern "C" {
#endif

inline int __fpclassifyf(float __value);

inline int __fpclassifyd(double __value);

int __fpclassifyl(long double __value);

#ifdef __cplusplus
};  // extern "C"
#endif

#ifdef __cplusplus
};
#endif

#define DEG_TO_RAD(degrees) (degrees * (M_PI / 180.0f))
#define RAD_TO_DEG(radians) (radians * (180.0f / M_PI))

#define fpclassify(x)                                                                                                                                \
    ((sizeof(x) == sizeof(float))  ? __fpclassifyf((float)(x)) :                                                                                     \
     (sizeof(x) == sizeof(double)) ? __fpclassifyd((double)(x)) :                                                                                    \
                                     __fpclassifyl((long double)(x)))

#define isnan(x) (fpclassify(x) == FP_NAN)
#define isinf(x) (fpclassify(x) == FP_INFINITE)

#endif  // CMATH_H
