Home | History | Annotate | Download | only in include
      1 /**
      2  * This file has no copyright assigned and is placed in the Public Domain.
      3  * This file is part of the mingw-w64 runtime package.
      4  * No warranty is given; refer to the file DISCLAIMER.PD within this package.
      5  */
      6 #ifndef _MATH_H_
      7 #define _MATH_H_
      8 
      9 #if __GNUC__ >= 3
     10 #pragma GCC system_header
     11 #endif
     12 
     13 #include <crtdefs.h>
     14 
     15 struct _exception;
     16 
     17 #pragma pack(push,_CRT_PACKING)
     18 
     19 #define	_DOMAIN		1	/* domain error in argument */
     20 #define	_SING		2	/* singularity */
     21 #define	_OVERFLOW	3	/* range overflow */
     22 #define	_UNDERFLOW	4	/* range underflow */
     23 #define	_TLOSS		5	/* total loss of precision */
     24 #define	_PLOSS		6	/* partial loss of precision */
     25 
     26 #ifndef __STRICT_ANSI__
     27 #ifndef	NO_OLDNAMES
     28 
     29 #define	DOMAIN		_DOMAIN
     30 #define	SING		_SING
     31 #define	OVERFLOW	_OVERFLOW
     32 #define	UNDERFLOW	_UNDERFLOW
     33 #define	TLOSS		_TLOSS
     34 #define	PLOSS		_PLOSS
     35 
     36 #endif
     37 #endif
     38 
     39 #ifndef __STRICT_ANSI__
     40 #define M_E		2.7182818284590452354
     41 #define M_LOG2E		1.4426950408889634074
     42 #define M_LOG10E	0.43429448190325182765
     43 #define M_LN2		0.69314718055994530942
     44 #define M_LN10		2.30258509299404568402
     45 #define M_PI		3.14159265358979323846
     46 #define M_PI_2		1.57079632679489661923
     47 #define M_PI_4		0.78539816339744830962
     48 #define M_1_PI		0.31830988618379067154
     49 #define M_2_PI		0.63661977236758134308
     50 #define M_2_SQRTPI	1.12837916709551257390
     51 #define M_SQRT2		1.41421356237309504880
     52 #define M_SQRT1_2	0.70710678118654752440
     53 #endif
     54 
     55 #ifndef __STRICT_ANSI__
     56 /* See also float.h  */
     57 #ifndef __MINGW_FPCLASS_DEFINED
     58 #define __MINGW_FPCLASS_DEFINED 1
     59 /* IEEE 754 classication */
     60 #define	_FPCLASS_SNAN	0x0001	/* Signaling "Not a Number" */
     61 #define	_FPCLASS_QNAN	0x0002	/* Quiet "Not a Number" */
     62 #define	_FPCLASS_NINF	0x0004	/* Negative Infinity */
     63 #define	_FPCLASS_NN	0x0008	/* Negative Normal */
     64 #define	_FPCLASS_ND	0x0010	/* Negative Denormal */
     65 #define	_FPCLASS_NZ	0x0020	/* Negative Zero */
     66 #define	_FPCLASS_PZ	0x0040	/* Positive Zero */
     67 #define	_FPCLASS_PD	0x0080	/* Positive Denormal */
     68 #define	_FPCLASS_PN	0x0100	/* Positive Normal */
     69 #define	_FPCLASS_PINF	0x0200	/* Positive Infinity */
     70 #endif
     71 #endif
     72 
     73 #ifndef RC_INVOKED
     74 
     75 #ifdef __cplusplus
     76 extern "C" {
     77 #endif
     78 
     79 #ifndef __MINGW_SOFTMATH
     80 #define __MINGW_SOFTMATH
     81 
     82 /* IEEE float/double type shapes.  */
     83 
     84   typedef union __mingw_dbl_type_t {
     85     double x;
     86     unsigned long long val;
     87     __C89_NAMELESS struct {
     88       unsigned int low, high;
     89     } lh;
     90   } __mingw_dbl_type_t;
     91 
     92   typedef union __mingw_flt_type_t {
     93     float x;
     94     unsigned int val;
     95   } __mingw_flt_type_t;
     96 
     97   typedef union __mingw_ldbl_type_t
     98   {
     99     long double x;
    100     __C89_NAMELESS struct {
    101       unsigned int low, high;
    102       int sign_exponent : 16;
    103       int res1 : 16;
    104       int res0 : 32;
    105     } lh;
    106   } __mingw_ldbl_type_t;
    107 
    108 #endif
    109 
    110 #ifndef _HUGE
    111   extern double * __MINGW_IMP_SYMBOL(_HUGE);
    112 #define _HUGE	(* __MINGW_IMP_SYMBOL(_HUGE))
    113 #endif
    114 
    115 #if __MINGW_GNUC_PREREQ(3, 3)
    116 #define	HUGE_VAL __builtin_huge_val()
    117 #else
    118 #define HUGE_VAL _HUGE
    119 #endif
    120 
    121 #ifndef _EXCEPTION_DEFINED
    122 #define _EXCEPTION_DEFINED
    123   struct _exception {
    124     int type;
    125     const char *name;
    126     double arg1;
    127     double arg2;
    128     double retval;
    129   };
    130 
    131   void __mingw_raise_matherr (int typ, const char *name, double a1, double a2,
    132 			      double rslt);
    133   void __mingw_setusermatherr (int (__cdecl *)(struct _exception *));
    134   _CRTIMP void __setusermatherr(int (__cdecl *)(struct _exception *));
    135   #define __setusermatherr __mingw_setusermatherr
    136 #endif
    137 
    138   double __cdecl sin(double _X);
    139   double __cdecl cos(double _X);
    140   double __cdecl tan(double _X);
    141   double __cdecl sinh(double _X);
    142   double __cdecl cosh(double _X);
    143   double __cdecl tanh(double _X);
    144   double __cdecl asin(double _X);
    145   double __cdecl acos(double _X);
    146   double __cdecl atan(double _X);
    147   double __cdecl atan2(double _Y,double _X);
    148   double __cdecl exp(double _X);
    149   double __cdecl log(double _X);
    150   double __cdecl log10(double _X);
    151   double __cdecl pow(double _X,double _Y);
    152   double __cdecl sqrt(double _X);
    153   double __cdecl ceil(double _X);
    154   double __cdecl floor(double _X);
    155 
    156 /* 7.12.7.2 The fabs functions: Double in C89 */
    157   extern  float __cdecl fabsf (float x);
    158   extern long double __cdecl fabsl (long double);
    159   extern double __cdecl fabs (double _X);
    160 
    161 #ifndef __CRT__NO_INLINE
    162 #if !defined (__ia64__)
    163   __CRT_INLINE float __cdecl fabsf (float x)
    164   {
    165 #ifdef __x86_64__
    166     return __builtin_fabsf (x);
    167 #else
    168     float res = 0.0F;
    169     __asm__ __volatile__ ("fabs;" : "=t" (res) : "0" (x));
    170     return res;
    171 #endif
    172   }
    173 
    174   __CRT_INLINE long double __cdecl fabsl (long double x)
    175   {
    176     long double res = 0.0l;
    177     __asm__ __volatile__ ("fabs;" : "=t" (res) : "0" (x));
    178     return res;
    179   }
    180 
    181   __CRT_INLINE double __cdecl fabs (double x)
    182   {
    183 #ifdef __x86_64__
    184     return __builtin_fabs (x);
    185 #else
    186     double res = 0.0;
    187     __asm__ __volatile__ ("fabs;" : "=t" (res) : "0" (x));
    188     return res;
    189 #endif
    190   }
    191 #endif
    192 #endif
    193 
    194   double __cdecl ldexp(double _X,int _Y);
    195   double __cdecl frexp(double _X,int *_Y);
    196   double __cdecl modf(double _X,double *_Y);
    197   double __cdecl fmod(double _X,double _Y);
    198 
    199   void __cdecl sincos (double __x, double *p_sin, double *p_cos);
    200   void __cdecl sincosl (long double __x, long double *p_sin, long double *p_cos);
    201   void __cdecl sincosf (float __x, float *p_sin, float *p_cos);
    202 
    203 #ifndef _CRT_ABS_DEFINED
    204 #define _CRT_ABS_DEFINED
    205   int __cdecl abs(int _X);
    206   long __cdecl labs(long _X);
    207 #endif
    208 #ifndef _CRT_ATOF_DEFINED
    209 #define _CRT_ATOF_DEFINED
    210   double __cdecl atof(const char *_String);
    211   double __cdecl _atof_l(const char *_String,_locale_t _Locale);
    212 #endif
    213 
    214 #define EDOM 33
    215 #define ERANGE 34
    216 
    217 #ifndef __STRICT_ANSI__
    218 
    219 #ifndef _COMPLEX_DEFINED
    220 #define _COMPLEX_DEFINED
    221   struct _complex {
    222     double x;
    223     double y;
    224   };
    225 #endif
    226 
    227   _CRTIMP double __cdecl _cabs(struct _complex _ComplexA);
    228   double __cdecl _hypot(double _X,double _Y);
    229   _CRTIMP double __cdecl _j0(double _X);
    230   _CRTIMP double __cdecl _j1(double _X);
    231   _CRTIMP double __cdecl _jn(int _X,double _Y);
    232   _CRTIMP double __cdecl _y0(double _X);
    233   _CRTIMP double __cdecl _y1(double _X);
    234   _CRTIMP double __cdecl _yn(int _X,double _Y);
    235 #ifndef _CRT_MATHERR_DEFINED
    236 #define _CRT_MATHERR_DEFINED
    237   _CRTIMP int __cdecl _matherr (struct _exception *);
    238 #endif
    239 
    240 /* These are also declared in Mingw float.h; needed here as well to work
    241    around GCC build issues.  */
    242 /* BEGIN FLOAT.H COPY */
    243 /*
    244  * IEEE recommended functions
    245  */
    246 #ifndef _SIGN_DEFINED
    247 #define _SIGN_DEFINED
    248   _CRTIMP double __cdecl _chgsign (double _X);
    249   _CRTIMP double __cdecl _copysign (double _Number,double _Sign);
    250   _CRTIMP double __cdecl _logb (double);
    251   _CRTIMP double __cdecl _nextafter (double, double);
    252   _CRTIMP double __cdecl _scalb (double, long);
    253   _CRTIMP int __cdecl _finite (double);
    254   _CRTIMP int __cdecl _fpclass (double);
    255   _CRTIMP int __cdecl _isnan (double);
    256 #endif
    257 
    258 /* END FLOAT.H COPY */
    259 
    260 #if !defined(NO_OLDNAMES)
    261 
    262 _CRTIMP double __cdecl j0 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    263 _CRTIMP double __cdecl j1 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    264 _CRTIMP double __cdecl jn (int, double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    265 _CRTIMP double __cdecl y0 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    266 _CRTIMP double __cdecl y1 (double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    267 _CRTIMP double __cdecl yn (int, double) __MINGW_ATTRIB_DEPRECATED_MSVC2005;
    268 
    269 _CRTIMP double __cdecl chgsign (double);
    270 /*
    271  * scalb() is a GCC built-in.
    272  * Exclude this _scalb() stub; the semantics are incompatible
    273  * with the built-in implementation.
    274  *
    275 _CRTIMP double __cdecl scalb (double, long);
    276  *
    277  */
    278   _CRTIMP int __cdecl finite (double);
    279   _CRTIMP int __cdecl fpclass (double);
    280 
    281 #define FP_SNAN    _FPCLASS_SNAN
    282 #define FP_QNAN    _FPCLASS_QNAN
    283 #define FP_NINF    _FPCLASS_NINF
    284 #define FP_PINF    _FPCLASS_PINF
    285 #define FP_NDENORM _FPCLASS_ND
    286 #define FP_PDENORM _FPCLASS_PD
    287 #define FP_NZERO   _FPCLASS_NZ
    288 #define FP_PZERO   _FPCLASS_PZ
    289 #define FP_NNORM   _FPCLASS_NN
    290 #define FP_PNORM   _FPCLASS_PN
    291 
    292 #endif /* !defined (_NO_OLDNAMES) && !define (NO_OLDNAMES) */
    293 
    294 #if(defined(_X86_) && !defined(__x86_64))
    295   _CRTIMP int __cdecl _set_SSE2_enable(int _Flag);
    296 #endif
    297 
    298 #endif
    299 
    300 #ifndef __NO_ISOCEXT
    301 #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
    302 	|| !defined __STRICT_ANSI__ || defined __cplusplus
    303 
    304 #if __MINGW_GNUC_PREREQ(3, 3)
    305 #define HUGE_VALF	__builtin_huge_valf()
    306 #define HUGE_VALL	__builtin_huge_vall()
    307 #define INFINITY	__builtin_inf()
    308 #define NAN		__builtin_nan("")
    309 #else
    310 extern const float __INFF;
    311 #define HUGE_VALF __INFF
    312 extern const long double  __INFL;
    313 #define HUGE_VALL __INFL
    314 #define INFINITY HUGE_VALF
    315 extern const double __QNAN;
    316 #define NAN __QNAN
    317 #endif /* __MINGW_GNUC_PREREQ(3, 3) */
    318 
    319 /* Use the compiler's builtin define for FLT_EVAL_METHOD to
    320    set float_t and double_t.  */
    321 #if defined (__x86_64__) || defined(__FLT_EVAL_METHOD__)
    322 # if defined (__x86_64__) || ( __FLT_EVAL_METHOD__== 0)
    323 typedef float float_t;
    324 typedef double double_t;
    325 # elif (__FLT_EVAL_METHOD__ == 1)
    326 typedef double float_t;
    327 typedef double double_t;
    328 # else /* (__FLT_EVAL_METHOD__ == 2) default ix87 FPU */
    329 typedef long double float_t;
    330 typedef long double double_t;
    331 #endif
    332 #else /* ix87 FPU default */
    333 typedef long double float_t;
    334 typedef long double double_t;
    335 #endif
    336 
    337 /* 7.12.3.1 */
    338 /*
    339    Return values for fpclassify.
    340    These are based on Intel x87 fpu condition codes
    341    in the high byte of status word and differ from
    342    the return values for MS IEEE 754 extension _fpclass()
    343 */
    344 #define FP_NAN		0x0100
    345 #define FP_NORMAL	0x0400
    346 #define FP_INFINITE	(FP_NAN | FP_NORMAL)
    347 #define FP_ZERO		0x4000
    348 #define FP_SUBNORMAL	(FP_NORMAL | FP_ZERO)
    349 /* 0x0200 is signbit mask */
    350 
    351 /*
    352   We can't inline float or double, because we want to ensure truncation
    353   to semantic type before classification.
    354   (A normal long double value might become subnormal when
    355   converted to double, and zero when converted to float.)
    356 */
    357 
    358   extern int __cdecl __fpclassifyl (long double);
    359   extern int __cdecl __fpclassifyf (float);
    360   extern int __cdecl __fpclassify (double);
    361 
    362 #ifndef __CRT__NO_INLINE
    363   __CRT_INLINE int __cdecl __fpclassifyl (long double x) {
    364     unsigned short sw;
    365     __asm__ __volatile__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
    366     return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
    367   }
    368   __CRT_INLINE int __cdecl __fpclassify (double x) {
    369 #ifdef __x86_64__
    370     __mingw_dbl_type_t hlp;
    371     unsigned int l, h;
    372 
    373     hlp.x = x;
    374     h = hlp.lh.high;
    375     l = hlp.lh.low | (h & 0xfffff);
    376     h &= 0x7ff00000;
    377     if ((h | l) == 0)
    378       return FP_ZERO;
    379     if (!h)
    380       return FP_SUBNORMAL;
    381     if (h == 0x7ff00000)
    382       return (l ? FP_NAN : FP_INFINITE);
    383     return FP_NORMAL;
    384 #else
    385     unsigned short sw;
    386     __asm__ __volatile__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
    387     return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
    388 #endif
    389   }
    390   __CRT_INLINE int __cdecl __fpclassifyf (float x) {
    391 #ifdef __x86_64__
    392     __mingw_flt_type_t hlp;
    393 
    394     hlp.x = x;
    395     hlp.val &= 0x7fffffff;
    396     if (hlp.val == 0)
    397       return FP_ZERO;
    398     if (hlp.val < 0x800000)
    399       return FP_SUBNORMAL;
    400     if (hlp.val >= 0x7f800000)
    401       return (hlp.val > 0x7f800000 ? FP_NAN : FP_INFINITE);
    402     return FP_NORMAL;
    403 #else
    404     unsigned short sw;
    405     __asm__ __volatile__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
    406     return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
    407 #endif
    408   }
    409 #endif
    410 
    411 #define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x)	  \
    412   : sizeof (x) == sizeof (double) ? __fpclassify (x) \
    413   : __fpclassifyl (x))
    414 
    415 /* 7.12.3.2 */
    416 #define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
    417 
    418 /* 7.12.3.3 */
    419 #define isinf(x) (fpclassify(x) == FP_INFINITE)
    420 
    421 /* 7.12.3.4 */
    422 /* We don't need to worry about truncation here:
    423    A NaN stays a NaN. */
    424 
    425   extern int __cdecl __isnan (double);
    426   extern int __cdecl __isnanf (float);
    427   extern int __cdecl __isnanl (long double);
    428 
    429 #ifndef __CRT__NO_INLINE
    430   __CRT_INLINE int __cdecl __isnan (double _x)
    431   {
    432 #ifdef __x86_64__
    433     __mingw_dbl_type_t hlp;
    434     int l, h;
    435 
    436     hlp.x = _x;
    437     l = hlp.lh.low;
    438     h = hlp.lh.high & 0x7fffffff;
    439     h |= (unsigned int) (l | -l) >> 31;
    440     h = 0x7ff00000 - h;
    441     return (int) ((unsigned int) h) >> 31;
    442 #else
    443     unsigned short sw;
    444     __asm__ __volatile__ ("fxam;"
    445       "fstsw %%ax": "=a" (sw) : "t" (_x));
    446     return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
    447       == FP_NAN;
    448 #endif
    449   }
    450 
    451   __CRT_INLINE int __cdecl __isnanf (float _x)
    452   {
    453 #ifdef __x86_64__
    454     __mingw_flt_type_t hlp;
    455     int i;
    456 
    457     hlp.x = _x;
    458     i = hlp.val & 0x7fffffff;
    459     i = 0x7f800000 - i;
    460     return (int) (((unsigned int) i) >> 31);
    461 #else
    462     unsigned short sw;
    463     __asm__ __volatile__ ("fxam;"
    464       "fstsw %%ax": "=a" (sw) : "t" (_x));
    465     return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
    466       == FP_NAN;
    467 #endif
    468   }
    469 
    470   __CRT_INLINE int __cdecl __isnanl (long double _x)
    471   {
    472     unsigned short sw;
    473     __asm__ __volatile__ ("fxam;"
    474       "fstsw %%ax": "=a" (sw) : "t" (_x));
    475     return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
    476       == FP_NAN;
    477   }
    478 #endif
    479 
    480 #define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x)	\
    481   : sizeof (x) == sizeof (double) ? __isnan (x)	\
    482   : __isnanl (x))
    483 
    484 /* 7.12.3.5 */
    485 #define isnormal(x) (fpclassify(x) == FP_NORMAL)
    486 
    487 /* 7.12.3.6 The signbit macro */
    488   extern int __cdecl __signbit (double);
    489   extern int __cdecl __signbitf (float);
    490   extern int __cdecl __signbitl (long double);
    491 #ifndef __CRT__NO_INLINE
    492   __CRT_INLINE int __cdecl __signbit (double x) {
    493 #ifdef __x86_64__
    494     __mingw_dbl_type_t hlp;
    495 
    496     hlp.x = x;
    497     return ((hlp.lh.high & 0x80000000) != 0);
    498 #else
    499     unsigned short stw;
    500     __asm__ __volatile__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
    501     return stw & 0x0200;
    502 #endif
    503   }
    504 
    505   __CRT_INLINE int __cdecl __signbitf (float x) {
    506 #ifdef __x86_64__
    507     __mingw_flt_type_t hlp;
    508     hlp.x = x;
    509     return ((hlp.val & 0x80000000) != 0);
    510 #else
    511     unsigned short stw;
    512     __asm__ __volatile__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
    513     return stw & 0x0200;
    514 #endif
    515   }
    516 
    517   __CRT_INLINE int __cdecl __signbitl (long double x) {
    518     unsigned short stw;
    519     __asm__ __volatile__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
    520     return stw & 0x0200;
    521   }
    522 #endif
    523 
    524 #define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x)	\
    525   : sizeof (x) == sizeof (double) ? __signbit (x)	\
    526   : __signbitl (x))
    527 
    528 /* 7.12.4 Trigonometric functions: Double in C89 */
    529   extern float __cdecl sinf(float _X);
    530   extern long double __cdecl sinl(long double);
    531 
    532   extern float __cdecl cosf(float _X);
    533   extern long double __cdecl cosl(long double);
    534 
    535   extern float __cdecl tanf(float _X);
    536   extern long double __cdecl tanl(long double);
    537   extern float __cdecl asinf(float _X);
    538   extern long double __cdecl asinl(long double);
    539 
    540   extern float __cdecl acosf (float);
    541   extern long double __cdecl acosl (long double);
    542 
    543   extern float __cdecl atanf (float);
    544   extern long double __cdecl atanl (long double);
    545 
    546   extern float __cdecl atan2f (float, float);
    547   extern long double __cdecl atan2l (long double, long double);
    548 
    549 /* 7.12.5 Hyperbolic functions: Double in C89  */
    550   extern float __cdecl sinhf(float _X);
    551 #ifndef __CRT__NO_INLINE
    552   __CRT_INLINE float sinhf(float _X) { return ((float)sinh((double)_X)); }
    553 #endif
    554   extern long double __cdecl sinhl(long double);
    555 
    556   extern float __cdecl coshf(float _X);
    557 #ifndef __CRT__NO_INLINE
    558   __CRT_INLINE float coshf(float _X) { return ((float)cosh((double)_X)); }
    559 #endif
    560   extern long double __cdecl coshl(long double);
    561 
    562   extern float __cdecl tanhf(float _X);
    563 #ifndef __CRT__NO_INLINE
    564   __CRT_INLINE float tanhf(float _X) { return ((float)tanh((double)_X)); }
    565 #endif
    566   extern long double __cdecl tanhl(long double);
    567 
    568 /* Inverse hyperbolic trig functions  */
    569 /* 7.12.5.1 */
    570   extern double __cdecl acosh (double);
    571   extern float __cdecl acoshf (float);
    572   extern long double __cdecl acoshl (long double);
    573 
    574 /* 7.12.5.2 */
    575   extern double __cdecl asinh (double);
    576   extern float __cdecl asinhf (float);
    577   extern long double __cdecl asinhl (long double);
    578 
    579 /* 7.12.5.3 */
    580   extern double __cdecl atanh (double);
    581   extern float __cdecl atanhf  (float);
    582   extern long double __cdecl atanhl (long double);
    583 
    584 /* Exponentials and logarithms  */
    585 /* 7.12.6.1 Double in C89 */
    586   extern float __cdecl expf(float _X);
    587 #ifndef __CRT__NO_INLINE
    588   __CRT_INLINE float expf(float _X) { return ((float)exp((double)_X)); }
    589 #endif
    590   extern long double __cdecl expl(long double);
    591 
    592 /* 7.12.6.2 */
    593   extern double __cdecl exp2(double);
    594   extern float __cdecl exp2f(float);
    595   extern long double __cdecl exp2l(long double);
    596 
    597 /* 7.12.6.3 The expm1 functions */
    598 /* TODO: These could be inlined */
    599   extern double __cdecl expm1(double);
    600   extern float __cdecl expm1f(float);
    601   extern long double __cdecl expm1l(long double);
    602 
    603 /* 7.12.6.4 Double in C89 */
    604   extern float frexpf(float _X,int *_Y);
    605 #ifndef __CRT__NO_INLINE
    606   __CRT_INLINE float frexpf(float _X,int *_Y) { return ((float)frexp((double)_X,_Y)); }
    607 #endif
    608   extern long double __cdecl frexpl(long double,int *);
    609 
    610 /* 7.12.6.5 */
    611 #define FP_ILOGB0 ((int)0x80000000)
    612 #define FP_ILOGBNAN ((int)0x80000000)
    613   extern int __cdecl ilogb (double);
    614   extern int __cdecl ilogbf (float);
    615   extern int __cdecl ilogbl (long double);
    616 
    617 /* 7.12.6.6  Double in C89 */
    618   extern float __cdecl ldexpf(float _X,int _Y);
    619 #ifndef __CRT__NO_INLINE
    620   __CRT_INLINE float __cdecl ldexpf (float x, int expn) { return (float) ldexp ((double)x, expn); }
    621 #endif
    622   extern long double __cdecl ldexpl (long double, int);
    623 
    624 /* 7.12.6.7 Double in C89 */
    625   extern float __cdecl logf (float);
    626   extern long double __cdecl logl(long double);
    627 
    628 /* 7.12.6.8 Double in C89 */
    629   extern float __cdecl log10f (float);
    630   extern long double __cdecl log10l(long double);
    631 
    632 /* 7.12.6.9 */
    633   extern double __cdecl log1p(double);
    634   extern float __cdecl log1pf(float);
    635   extern long double __cdecl log1pl(long double);
    636 
    637 /* 7.12.6.10 */
    638   extern double __cdecl log2 (double);
    639   extern float __cdecl log2f (float);
    640   extern long double __cdecl log2l (long double);
    641 
    642 /* 7.12.6.11 */
    643   extern double __cdecl logb (double);
    644   extern float __cdecl logbf (float);
    645   extern long double __cdecl logbl (long double);
    646 
    647 /* Inline versions.  GCC-4.0+ can do a better fast-math optimization
    648    with __builtins. */
    649 #ifndef __CRT__NO_INLINE
    650 #if !(__MINGW_GNUC_PREREQ (4, 0) && defined (__FAST_MATH__))
    651   __CRT_INLINE double __cdecl logb (double x)
    652   {
    653 #ifdef __x86_64__
    654   __mingw_dbl_type_t hlp;
    655   int lx, hx;
    656 
    657   hlp.x = x;
    658   lx = hlp.lh.low;
    659   hx = hlp.lh.high & 0x7fffffff; /* high |x| */
    660   if ((hx | lx) == 0)
    661     return -1.0 / fabs (x);
    662   if (hx >= 0x7ff00000)
    663     return x * x;
    664   if ((hx >>= 20) == 0) /* IEEE 754 logb */
    665     return -1022.0;
    666   return (double) (hx - 1023);
    667 #else
    668     double res = 0.0;
    669     __asm__ __volatile__ ("fxtract\n\t"
    670       "fstp	%%st" : "=t" (res) : "0" (x));
    671     return res;
    672 #endif
    673   }
    674 
    675   __CRT_INLINE float __cdecl logbf (float x)
    676   {
    677 #ifdef __x86_64__
    678     int v;
    679     __mingw_flt_type_t hlp;
    680 
    681     hlp.x = x;
    682     v = hlp.val & 0x7fffffff;                     /* high |x| */
    683     if (!v)
    684       return (float)-1.0 / fabsf (x);
    685     if (v >= 0x7f800000)
    686     return x * x;
    687   if ((v >>= 23) == 0) /* IEEE 754 logb */
    688     return -126.0;
    689   return (float) (v - 127);
    690 #else
    691     float res = 0.0F;
    692     __asm__ __volatile__ ("fxtract\n\t"
    693       "fstp	%%st" : "=t" (res) : "0" (x));
    694     return res;
    695 #endif
    696   }
    697 
    698   __CRT_INLINE long double __cdecl logbl (long double x)
    699   {
    700     long double res = 0.0l;
    701     __asm__ __volatile__ ("fxtract\n\t"
    702       "fstp	%%st" : "=t" (res) : "0" (x));
    703     return res;
    704   }
    705 #endif /* !defined __FAST_MATH__ || !__MINGW_GNUC_PREREQ (4, 0) */
    706 #endif /* __CRT__NO_INLINE */
    707 
    708 /* 7.12.6.12  Double in C89 */
    709   extern float __cdecl modff (float, float*);
    710   extern long double __cdecl modfl (long double, long double*);
    711 
    712 /* 7.12.6.13 */
    713   extern double __cdecl scalbn (double, int);
    714   extern float __cdecl scalbnf (float, int);
    715   extern long double __cdecl scalbnl (long double, int);
    716 
    717   extern double __cdecl scalbln (double, long);
    718   extern float __cdecl scalblnf (float, long);
    719   extern long double __cdecl scalblnl (long double, long);
    720 
    721 /* 7.12.7.1 */
    722 /* Implementations adapted from Cephes versions */
    723   extern double __cdecl cbrt (double);
    724   extern float __cdecl cbrtf (float);
    725   extern long double __cdecl cbrtl (long double);
    726 
    727 /* 7.12.7.3  */
    728   extern double __cdecl hypot (double, double) __MINGW_ATTRIB_DEPRECATED_MSVC2005; /* in libmoldname.a */
    729   extern float __cdecl hypotf (float x, float y);
    730 #ifndef __CRT__NO_INLINE
    731   __CRT_INLINE float __cdecl hypotf (float x, float y) { return (float) hypot ((double)x, (double)y);}
    732 #endif
    733   extern long double __cdecl hypotl (long double, long double);
    734 
    735 /* 7.12.7.4 The pow functions. Double in C89 */
    736   extern float __cdecl powf(float _X,float _Y);
    737 #ifndef __CRT__NO_INLINE
    738   __CRT_INLINE float powf(float _X,float _Y) { return ((float)pow((double)_X,(double)_Y)); }
    739 #endif
    740   extern long double __cdecl powl (long double, long double);
    741 
    742 /* 7.12.7.5 The sqrt functions. Double in C89. */
    743   extern float __cdecl sqrtf (float);
    744   extern long double sqrtl(long double);
    745 
    746 /* 7.12.8.1 The erf functions  */
    747   extern double __cdecl erf (double);
    748   extern float __cdecl erff (float);
    749   extern long double __cdecl erfl (long double);
    750 
    751 /* 7.12.8.2 The erfc functions  */
    752   extern double __cdecl erfc (double);
    753   extern float __cdecl erfcf (float);
    754   extern long double __cdecl erfcl (long double);
    755 
    756 /* 7.12.8.3 The lgamma functions */
    757   extern double __cdecl lgamma (double);
    758   extern float __cdecl lgammaf (float);
    759   extern long double __cdecl lgammal (long double);
    760 
    761   extern int signgam;
    762 
    763 /* 7.12.8.4 The tgamma functions */
    764   extern double __cdecl tgamma (double);
    765   extern float __cdecl tgammaf (float);
    766   extern long double __cdecl tgammal (long double);
    767 
    768 /* 7.12.9.1 Double in C89 */
    769   extern float __cdecl ceilf (float);
    770   extern long double __cdecl ceill (long double);
    771 
    772 /* 7.12.9.2 Double in C89 */
    773   extern float __cdecl floorf (float);
    774   extern long double __cdecl floorl (long double);
    775 
    776 /* 7.12.9.3 */
    777   extern double __cdecl nearbyint ( double);
    778   extern float __cdecl nearbyintf (float);
    779   extern long double __cdecl nearbyintl (long double);
    780 
    781 /* 7.12.9.4 */
    782 /* round, using fpu control word settings */
    783 extern double __cdecl rint (double);
    784 extern float __cdecl rintf (float);
    785 extern long double __cdecl rintl (long double);
    786 
    787 /* 7.12.9.5 */
    788 extern long __cdecl lrint (double);
    789 extern long __cdecl lrintf (float);
    790 extern long __cdecl lrintl (long double);
    791 
    792 __MINGW_EXTENSION long long __cdecl llrint (double);
    793 __MINGW_EXTENSION long long __cdecl llrintf (float);
    794 __MINGW_EXTENSION long long __cdecl llrintl (long double);
    795 
    796 /* Inline versions of above.
    797    GCC 4.0+ can do a better fast-math job with __builtins. */
    798 
    799 #ifndef __CRT__NO_INLINE
    800 #if !(__MINGW_GNUC_PREREQ (4, 0) && defined __FAST_MATH__ )
    801   __CRT_INLINE double __cdecl rint (double x)
    802   {
    803     double retval = 0.0;
    804     __asm__ __volatile__ ("frndint;": "=t" (retval) : "0" (x));
    805     return retval;
    806   }
    807 
    808   __CRT_INLINE float __cdecl rintf (float x)
    809   {
    810     float retval = 0.0;
    811     __asm__ __volatile__ ("frndint;" : "=t" (retval) : "0" (x) );
    812     return retval;
    813   }
    814 
    815   __CRT_INLINE long double __cdecl rintl (long double x)
    816   {
    817     long double retval = 0.0l;
    818     __asm__ __volatile__ ("frndint;" : "=t" (retval) : "0" (x) );
    819     return retval;
    820   }
    821 
    822   __CRT_INLINE long __cdecl lrint (double x)
    823   {
    824     long retval = 0;
    825     __asm__ __volatile__							      \
    826       ("fistpl %0"  : "=m" (retval) : "t" (x) : "st");				      \
    827       return retval;
    828   }
    829 
    830   __CRT_INLINE long __cdecl lrintf (float x)
    831   {
    832     long retval = 0;
    833     __asm__ __volatile__							      \
    834       ("fistpl %0"  : "=m" (retval) : "t" (x) : "st");				      \
    835       return retval;
    836   }
    837 
    838   __CRT_INLINE long __cdecl lrintl (long double x)
    839   {
    840     long retval = 0;
    841     __asm__ __volatile__							      \
    842       ("fistpl %0"  : "=m" (retval) : "t" (x) : "st");				      \
    843       return retval;
    844   }
    845 
    846   __MINGW_EXTENSION __CRT_INLINE long long __cdecl llrint (double x)
    847   {
    848     __MINGW_EXTENSION long long retval = 0ll;
    849     __asm__ __volatile__							      \
    850       ("fistpll %0"  : "=m" (retval) : "t" (x) : "st");				      \
    851       return retval;
    852   }
    853 
    854   __MINGW_EXTENSION __CRT_INLINE long long __cdecl llrintf (float x)
    855   {
    856     __MINGW_EXTENSION long long retval = 0ll;
    857     __asm__ __volatile__							      \
    858       ("fistpll %0"  : "=m" (retval) : "t" (x) : "st");				      \
    859       return retval;
    860   }
    861 
    862   __MINGW_EXTENSION __CRT_INLINE long long __cdecl llrintl (long double x)
    863   {
    864     __MINGW_EXTENSION long long retval = 0ll;
    865     __asm__ __volatile__							      \
    866       ("fistpll %0"  : "=m" (retval) : "t" (x) : "st");				      \
    867       return retval;
    868   }
    869 #endif /* !__FAST_MATH__ || !__MINGW_GNUC_PREREQ (4,0)  */
    870 #endif /* !__CRT__NO_INLINE */
    871 
    872 /* 7.12.9.6 */
    873 /* round away from zero, regardless of fpu control word settings */
    874   extern double __cdecl round (double);
    875   extern float __cdecl roundf (float);
    876   extern long double __cdecl roundl (long double);
    877 
    878 /* 7.12.9.7  */
    879   extern long __cdecl lround (double);
    880   extern long __cdecl lroundf (float);
    881   extern long __cdecl lroundl (long double);
    882   __MINGW_EXTENSION long long __cdecl llround (double);
    883   __MINGW_EXTENSION long long __cdecl llroundf (float);
    884   __MINGW_EXTENSION long long __cdecl llroundl (long double);
    885 
    886 /* 7.12.9.8 */
    887 /* round towards zero, regardless of fpu control word settings */
    888   extern double __cdecl trunc (double);
    889   extern float __cdecl truncf (float);
    890   extern long double __cdecl truncl (long double);
    891 
    892 /* 7.12.10.1 Double in C89 */
    893   extern float __cdecl fmodf (float, float);
    894   extern long double __cdecl fmodl (long double, long double);
    895 
    896 /* 7.12.10.2 */
    897   extern double __cdecl remainder (double, double);
    898   extern float __cdecl remainderf (float, float);
    899   extern long double __cdecl remainderl (long double, long double);
    900 
    901 /* 7.12.10.3 */
    902   extern double __cdecl remquo(double, double, int *);
    903   extern float __cdecl remquof(float, float, int *);
    904   extern long double __cdecl remquol(long double, long double, int *);
    905 
    906 /* 7.12.11.1 */
    907   extern double __cdecl copysign (double, double); /* in libmoldname.a */
    908   extern float __cdecl copysignf (float, float);
    909   extern long double __cdecl copysignl (long double, long double);
    910 
    911 #ifndef __CRT__NO_INLINE
    912 #if !defined (__ia64__)
    913   __CRT_INLINE double __cdecl copysign (double x, double y)
    914   {
    915     __mingw_dbl_type_t hx, hy;
    916     hx.x = x; hy.x = y;
    917     hx.lh.high = (hx.lh.high & 0x7fffffff) | (hy.lh.high & 0x80000000);
    918     return hx.x;
    919   }
    920   __CRT_INLINE float __cdecl copysignf (float x, float y)
    921   {
    922     __mingw_flt_type_t hx, hy;
    923     hx.x = x; hy.x = y;
    924     hx.val = (hx.val & 0x7fffffff) | (hy.val & 0x80000000);
    925     return hx.x;
    926   }
    927 #endif
    928 #endif
    929 
    930 /* 7.12.11.2 Return a NaN */
    931   extern double __cdecl nan(const char *tagp);
    932   extern float __cdecl nanf(const char *tagp);
    933   extern long double __cdecl nanl(const char *tagp);
    934 
    935 #ifndef __STRICT_ANSI__
    936 #define _nan() nan("")
    937 #define _nanf() nanf("")
    938 #define _nanl() nanl("")
    939 #endif
    940 
    941 /* 7.12.11.3 */
    942   extern double __cdecl nextafter (double, double); /* in libmoldname.a */
    943   extern float __cdecl nextafterf (float, float);
    944   extern long double __cdecl nextafterl (long double, long double);
    945 
    946 /* 7.12.11.4 The nexttoward functions */
    947   extern double __cdecl nexttoward (double,  long double);
    948   extern float __cdecl nexttowardf (float,  long double);
    949   extern long double __cdecl nexttowardl (long double, long double);
    950 
    951 /* 7.12.12.1 */
    952 /*  x > y ? (x - y) : 0.0  */
    953   extern double __cdecl fdim (double x, double y);
    954   extern float __cdecl fdimf (float x, float y);
    955   extern long double __cdecl fdiml (long double x, long double y);
    956 
    957 /* fmax and fmin.
    958    NaN arguments are treated as missing data: if one argument is a NaN
    959    and the other numeric, then these functions choose the numeric
    960    value. */
    961 
    962 /* 7.12.12.2 */
    963   extern double __cdecl fmax  (double, double);
    964   extern float __cdecl fmaxf (float, float);
    965   extern long double __cdecl fmaxl (long double, long double);
    966 
    967 /* 7.12.12.3 */
    968   extern double __cdecl fmin (double, double);
    969   extern float __cdecl fminf (float, float);
    970   extern long double __cdecl fminl (long double, long double);
    971 
    972 /* 7.12.13.1 */
    973 /* return x * y + z as a ternary op */
    974   extern double __cdecl fma (double, double, double);
    975   extern float __cdecl fmaf (float, float, float);
    976   extern long double __cdecl fmal (long double, long double, long double);
    977 
    978 /* 7.12.14 */
    979 /*
    980  *  With these functions, comparisons involving quiet NaNs set the FP
    981  *  condition code to "unordered".  The IEEE floating-point spec
    982  *  dictates that the result of floating-point comparisons should be
    983  *  false whenever a NaN is involved, with the exception of the != op,
    984  *  which always returns true: yes, (NaN != NaN) is true).
    985  */
    986 
    987 #if __GNUC__ >= 3
    988 
    989 #define isgreater(x, y) __builtin_isgreater(x, y)
    990 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
    991 #define isless(x, y) __builtin_isless(x, y)
    992 #define islessequal(x, y) __builtin_islessequal(x, y)
    993 #define islessgreater(x, y) __builtin_islessgreater(x, y)
    994 #define isunordered(x, y) __builtin_isunordered(x, y)
    995 
    996 #else
    997 /*  helper  */
    998 #ifndef __CRT__NO_INLINE
    999   __CRT_INLINE int  __cdecl
   1000     __fp_unordered_compare (long double x, long double y){
   1001       unsigned short retval;
   1002       __asm__ __volatile__ ("fucom %%st(1);"
   1003 	"fnstsw;": "=a" (retval) : "t" (x), "u" (y));
   1004       return retval;
   1005   }
   1006 #endif
   1007 
   1008 #define isgreater(x, y) ((__fp_unordered_compare(x, y)  & 0x4500) == 0)
   1009 #define isless(x, y) ((__fp_unordered_compare (y, x)  & 0x4500) == 0)
   1010 #define isgreaterequal(x, y) ((__fp_unordered_compare (x, y)  & FP_INFINITE) == 0)
   1011 #define islessequal(x, y) ((__fp_unordered_compare(y, x)  & FP_INFINITE) == 0)
   1012 #define islessgreater(x, y) ((__fp_unordered_compare(x, y)  & FP_SUBNORMAL) == 0)
   1013 #define isunordered(x, y) ((__fp_unordered_compare(x, y)  & 0x4500) == 0x4500)
   1014 
   1015 #endif
   1016 
   1017 #endif /* __STDC_VERSION__ >= 199901L */
   1018 #endif /* __NO_ISOCEXT */
   1019 
   1020 #if defined(_X86_) && !defined(__x86_64)
   1021   _CRTIMP float __cdecl _hypotf(float _X,float _Y);
   1022 #endif
   1023 
   1024 #if !defined(__ia64__)
   1025    _CRTIMP float __cdecl _copysignf (float _Number,float _Sign);
   1026    _CRTIMP float __cdecl _chgsignf (float _X);
   1027    _CRTIMP float __cdecl _logbf(float _X);
   1028    _CRTIMP float __cdecl _nextafterf(float _X,float _Y);
   1029    _CRTIMP int __cdecl _finitef(float _X);
   1030    _CRTIMP int __cdecl _isnanf(float _X);
   1031    _CRTIMP int __cdecl _fpclassf(float _X);
   1032 #endif
   1033 
   1034 #ifdef _SIGN_DEFINED
   1035    extern long double __cdecl _chgsignl (long double);
   1036 #define _copysignl copysignl
   1037 #endif /* _SIGN_DEFINED */
   1038 
   1039 #define _hypotl hypotl
   1040 
   1041 #ifndef	NO_OLDNAMES
   1042 #define matherr _matherr
   1043 #define HUGE	_HUGE
   1044 #endif
   1045 
   1046 #ifdef __cplusplus
   1047 }
   1048 #endif
   1049 
   1050 #endif	/* Not RC_INVOKED */
   1051 
   1052 #pragma pack(pop)
   1053 
   1054 #endif /* End _MATH_H_ */
   1055 
   1056