Create a branch for network fixes.
[reactos.git] / include / crt / math.h
1 /*
2 * math.h
3 * This file has no copyright assigned and is placed in the Public Domain.
4 * This file is a part of the mingw-runtime package.
5 * No warranty is given; refer to the file DISCLAIMER within the package.
6 *
7 * Mathematical functions.
8 *
9 */
10
11
12 #ifndef _MATH_H_
13 #define _MATH_H_
14
15 #if __GNUC__ >= 3
16 #pragma GCC system_header
17 #endif
18
19 /* All the headers include this file. */
20 #include <_mingw.h>
21
22 /*
23 * Types for the _exception structure.
24 */
25
26 #define _DOMAIN 1 /* domain error in argument */
27 #define _SING 2 /* singularity */
28 #define _OVERFLOW 3 /* range overflow */
29 #define _UNDERFLOW 4 /* range underflow */
30 #define _TLOSS 5 /* total loss of precision */
31 #define _PLOSS 6 /* partial loss of precision */
32
33 /*
34 * Exception types with non-ANSI names for compatibility.
35 */
36
37 #ifndef __STRICT_ANSI__
38 #ifndef _NO_OLDNAMES
39
40 #define DOMAIN _DOMAIN
41 #define SING _SING
42 #define OVERFLOW _OVERFLOW
43 #define UNDERFLOW _UNDERFLOW
44 #define TLOSS _TLOSS
45 #define PLOSS _PLOSS
46
47 #endif /* Not _NO_OLDNAMES */
48 #endif /* Not __STRICT_ANSI__ */
49
50
51 /* Traditional/XOPEN math constants (double precison) */
52 #ifndef __STRICT_ANSI__
53 #define M_E 2.7182818284590452354
54 #define M_LOG2E 1.4426950408889634074
55 #define M_LOG10E 0.43429448190325182765
56 #define M_LN2 0.69314718055994530942
57 #define M_LN10 2.30258509299404568402
58 #define M_PI 3.14159265358979323846
59 #define M_PI_2 1.57079632679489661923
60 #define M_PI_4 0.78539816339744830962
61 #define M_1_PI 0.31830988618379067154
62 #define M_2_PI 0.63661977236758134308
63 #define M_2_SQRTPI 1.12837916709551257390
64 #define M_SQRT2 1.41421356237309504880
65 #define M_SQRT1_2 0.70710678118654752440
66 #endif
67
68 /* These are also defined in Mingw float.h; needed here as well to work
69 around GCC build issues. */
70 #ifndef __STRICT_ANSI__
71 #ifndef __MINGW_FPCLASS_DEFINED
72 #define __MINGW_FPCLASS_DEFINED 1
73 /* IEEE 754 classication */
74 #define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
75 #define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
76 #define _FPCLASS_NINF 0x0004 /* Negative Infinity */
77 #define _FPCLASS_NN 0x0008 /* Negative Normal */
78 #define _FPCLASS_ND 0x0010 /* Negative Denormal */
79 #define _FPCLASS_NZ 0x0020 /* Negative Zero */
80 #define _FPCLASS_PZ 0x0040 /* Positive Zero */
81 #define _FPCLASS_PD 0x0080 /* Positive Denormal */
82 #define _FPCLASS_PN 0x0100 /* Positive Normal */
83 #define _FPCLASS_PINF 0x0200 /* Positive Infinity */
84 #endif /* __MINGW_FPCLASS_DEFINED */
85 #endif /* Not __STRICT_ANSI__ */
86
87 #ifndef RC_INVOKED
88
89 #ifdef __cplusplus
90 extern "C" {
91 #endif
92
93 /*
94 * HUGE_VAL is returned by strtod when the value would overflow the
95 * representation of 'double'. There are other uses as well.
96 *
97 * __imp__HUGE is a pointer to the actual variable _HUGE in
98 * MSVCRT.DLL. If we used _HUGE directly we would get a pointer
99 * to a thunk function.
100 *
101 * NOTE: The CRTDLL version uses _HUGE_dll instead.
102 */
103
104 #if __MINGW_GNUC_PREREQ(3, 3)
105 #define HUGE_VAL __builtin_huge_val()
106 #else
107
108 #ifndef __DECLSPEC_SUPPORTED
109
110 #ifdef __MSVCRT__
111 extern double* _imp___HUGE;
112 #define HUGE_VAL (*_imp___HUGE)
113 #else
114 /* CRTDLL */
115 extern double* _imp___HUGE_dll;
116 #define HUGE_VAL (*_imp___HUGE_dll)
117 #endif
118
119 #else /* __DECLSPEC_SUPPORTED */
120
121 #ifdef __MSVCRT__
122 __MINGW_IMPORT double _HUGE;
123 #define HUGE_VAL _HUGE
124 #else
125 /* CRTDLL */
126 __MINGW_IMPORT double _HUGE_dll;
127 #define HUGE_VAL _HUGE_dll
128 #endif
129
130 #endif /* __DECLSPEC_SUPPORTED */
131 #endif /* __MINGW_GNUC_PREREQ(3, 3) */
132
133
134 struct _exception
135 {
136 int type;
137 char *name;
138 double arg1;
139 double arg2;
140 double retval;
141 };
142
143 _CRTIMP double __cdecl sin (double);
144 _CRTIMP double __cdecl cos (double);
145 _CRTIMP double __cdecl tan (double);
146 _CRTIMP double __cdecl sinh (double);
147 _CRTIMP double __cdecl cosh (double);
148 _CRTIMP double __cdecl tanh (double);
149 _CRTIMP double __cdecl asin (double);
150 _CRTIMP double __cdecl acos (double);
151 _CRTIMP double __cdecl atan (double);
152 _CRTIMP double __cdecl atan2 (double, double);
153 _CRTIMP double __cdecl exp (double);
154 _CRTIMP double __cdecl log (double);
155 _CRTIMP double __cdecl log10 (double);
156 _CRTIMP double __cdecl pow (double, double);
157 _CRTIMP double __cdecl sqrt (double);
158 _CRTIMP double __cdecl ceil (double);
159 _CRTIMP double __cdecl floor (double);
160 _CRTIMP double __cdecl fabs (double);
161 _CRTIMP double __cdecl ldexp (double, int);
162 _CRTIMP double __cdecl frexp (double, int*);
163 _CRTIMP double __cdecl modf (double, double*);
164 _CRTIMP double __cdecl fmod (double, double);
165
166 /* Excess precision when using a 64-bit mantissa for FPU math ops can
167 cause unexpected results with some of the MSVCRT math functions. For
168 example, unless the function return value is stored (truncating to
169 53-bit mantissa), calls to pow with both x and y as integral values
170 sometimes produce a non-integral result.
171 One workaround is to reset the FPU env to 53-bit mantissa
172 by a call to fesetenv (FE_PC53_ENV). Amother is to force storage
173 of the return value of individual math functions using wrappers.
174 NB, using these wrappers will disable builtin math functions and
175 hence disable the folding of function results at compile time when
176 arguments are constant. */
177
178 #if 0
179 #define __DEFINE_FLOAT_STORE_MATHFN_D1(fn1) \
180 static __inline__ double \
181 __float_store_ ## fn1 (double x) \
182 { \
183 __volatile__ double res = (fn1) (x); \
184 return res; \
185 }
186
187 #define __DEFINE_FLOAT_STORE_MATHFN_D2(fn2) \
188 static __inline__ double \
189 __float_store_ ## fn2 (double x, double y) \
190 { \
191 __volatile__ double res = (fn2) (x, y); \
192 return res; \
193 }
194 #endif
195
196 /* For example, here is how to force the result of the pow function
197 to be stored: */
198 #if 0
199 #undef pow
200 /* Define the ___float_store_pow function and use it instead of pow(). */
201 __DEFINE_FLOAT_STORE_MATHFN_D2 (pow)
202 #define pow __float_store_pow
203 #endif
204
205 #ifndef __STRICT_ANSI__
206
207 /* Complex number (for _cabs). This is the MS version. The ISO
208 C99 counterpart _Complex is an intrinsic type in GCC and
209 'complex' is defined as a macro. See complex.h */
210 struct _complex
211 {
212 double x; /* Real part */
213 double y; /* Imaginary part */
214 };
215
216 _CRTIMP double __cdecl _cabs (struct _complex);
217
218 _CRTIMP double __cdecl _hypot (double, double);
219 _CRTIMP double __cdecl _j0 (double);
220 _CRTIMP double __cdecl _j1 (double);
221 _CRTIMP double __cdecl _jn (int, double);
222 _CRTIMP double __cdecl _y0 (double);
223 _CRTIMP double __cdecl _y1 (double);
224 _CRTIMP double __cdecl _yn (int, double);
225 _CRTIMP int __cdecl _matherr (struct _exception *);
226
227 /* These are also declared in Mingw float.h; needed here as well to work
228 around GCC build issues. */
229 /* BEGIN FLOAT.H COPY */
230 /*
231 * IEEE recommended functions
232 */
233
234 _CRTIMP double __cdecl _chgsign (double);
235 _CRTIMP double __cdecl _copysign (double, double);
236 _CRTIMP double __cdecl _logb (double);
237 _CRTIMP double __cdecl _nextafter (double, double);
238 _CRTIMP double __cdecl _scalb (double, long);
239
240 _CRTIMP int __cdecl _finite (double);
241 _CRTIMP int __cdecl _fpclass (double);
242 _CRTIMP int __cdecl _isnan (double);
243
244 /* END FLOAT.H COPY */
245
246
247 /*
248 * Non-underscored versions of non-ANSI functions.
249 * These reside in liboldnames.a.
250 */
251
252 #if !defined (_NO_OLDNAMES)
253
254 _CRTIMP double __cdecl j0 (double);
255 _CRTIMP double __cdecl j1 (double);
256 _CRTIMP double __cdecl jn (int, double);
257 _CRTIMP double __cdecl y0 (double);
258 _CRTIMP double __cdecl y1 (double);
259 _CRTIMP double __cdecl yn (int, double);
260
261 _CRTIMP double __cdecl chgsign (double);
262 _CRTIMP double __cdecl scalb (double, long);
263 _CRTIMP int __cdecl finite (double);
264 _CRTIMP int __cdecl fpclass (double);
265
266 #define FP_SNAN _FPCLASS_SNAN
267 #define FP_QNAN _FPCLASS_QNAN
268 #define FP_NINF _FPCLASS_NINF
269 #define FP_PINF _FPCLASS_PINF
270 #define FP_NDENORM _FPCLASS_ND
271 #define FP_PDENORM _FPCLASS_PD
272 #define FP_NZERO _FPCLASS_NZ
273 #define FP_PZERO _FPCLASS_PZ
274 #define FP_NNORM _FPCLASS_NN
275 #define FP_PNORM _FPCLASS_PN
276
277 #endif /* Not _NO_OLDNAMES */
278
279 /* This require msvcr70.dll or higher. */
280 #if __MSVCRT_VERSION__ >= 0x0700
281 _CRTIMP int __cdecl _set_SSE2_enable (int);
282 #endif /* __MSVCRT_VERSION__ >= 0x0700 */
283
284
285 #endif /* __STRICT_ANSI__ */
286
287
288 #ifndef __NO_ISOCEXT
289 #if (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L) \
290 || !defined __STRICT_ANSI__ || defined __cplusplus
291
292 #if __MINGW_GNUC_PREREQ(3, 3)
293 #define HUGE_VALF __builtin_huge_valf()
294 #define HUGE_VALL __builtin_huge_vall()
295 #define INFINITY __builtin_inf()
296 #define NAN __builtin_nan("")
297 #else
298 extern const float __INFF;
299 #define HUGE_VALF __INFF
300 extern const long double __INFL;
301 #define HUGE_VALL __INFL
302 #define INFINITY HUGE_VALF
303 extern const double __QNAN;
304 #define NAN __QNAN
305 #endif /* __MINGW_GNUC_PREREQ(3, 3) */
306
307 /* 7.12.3.1 */
308 /*
309 Return values for fpclassify.
310 These are based on Intel x87 fpu condition codes
311 in the high byte of status word and differ from
312 the return values for MS IEEE 754 extension _fpclass()
313 */
314 #define FP_NAN 0x0100
315 #define FP_NORMAL 0x0400
316 #define FP_INFINITE (FP_NAN | FP_NORMAL)
317 #define FP_ZERO 0x4000
318 #define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
319 /* 0x0200 is signbit mask */
320
321
322 /*
323 We can't inline float or double, because we want to ensure truncation
324 to semantic type before classification.
325 (A normal long double value might become subnormal when
326 converted to double, and zero when converted to float.)
327 */
328
329 extern int __cdecl __fpclassifyf (float);
330 extern int __cdecl __fpclassify (double);
331
332 __CRT_INLINE int __cdecl __fpclassifyl (long double x){
333 unsigned short sw;
334 __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
335 return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
336 }
337
338 #define fpclassify(x) (sizeof (x) == sizeof (float) ? __fpclassifyf (x) \
339 : sizeof (x) == sizeof (double) ? __fpclassify (x) \
340 : __fpclassifyl (x))
341
342 /* 7.12.3.2 */
343 #define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
344
345 /* 7.12.3.3 */
346 #define isinf(x) (fpclassify(x) == FP_INFINITE)
347
348 /* 7.12.3.4 */
349 /* We don't need to worry about trucation here:
350 A NaN stays a NaN. */
351
352 __CRT_INLINE int __cdecl __isnan (double _x)
353 {
354 unsigned short sw;
355 __asm__ ("fxam;"
356 "fstsw %%ax": "=a" (sw) : "t" (_x));
357 return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
358 == FP_NAN;
359 }
360
361 __CRT_INLINE int __cdecl __isnanf (float _x)
362 {
363 unsigned short sw;
364 __asm__ ("fxam;"
365 "fstsw %%ax": "=a" (sw) : "t" (_x));
366 return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
367 == FP_NAN;
368 }
369
370 __CRT_INLINE int __cdecl __isnanl (long double _x)
371 {
372 unsigned short sw;
373 __asm__ ("fxam;"
374 "fstsw %%ax": "=a" (sw) : "t" (_x));
375 return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
376 == FP_NAN;
377 }
378
379
380 #define isnan(x) (sizeof (x) == sizeof (float) ? __isnanf (x) \
381 : sizeof (x) == sizeof (double) ? __isnan (x) \
382 : __isnanl (x))
383
384 /* 7.12.3.5 */
385 #define isnormal(x) (fpclassify(x) == FP_NORMAL)
386
387 /* 7.12.3.6 The signbit macro */
388 __CRT_INLINE int __cdecl __signbit (double x) {
389 unsigned short stw;
390 __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
391 return (stw & 0x0200) != 0;
392 }
393
394 __CRT_INLINE int __cdecl __signbitf (float x) {
395 unsigned short stw;
396 __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
397 return (stw & 0x0200) != 0;
398 }
399
400 __CRT_INLINE int __cdecl __signbitl (long double x) {
401 unsigned short stw;
402 __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
403 return (stw & 0x0200) != 0;
404 }
405
406 #define signbit(x) (sizeof (x) == sizeof (float) ? __signbitf (x) \
407 : sizeof (x) == sizeof (double) ? __signbit (x) \
408 : __signbitl (x))
409
410 /* 7.12.4 Trigonometric functions: Double in C89 */
411 extern float __cdecl sinf (float);
412 extern long double __cdecl sinl (long double);
413
414 extern float __cdecl cosf (float);
415 extern long double __cdecl cosl (long double);
416
417 extern float __cdecl tanf (float);
418 extern long double __cdecl tanl (long double);
419
420 extern float __cdecl asinf (float);
421 extern long double __cdecl asinl (long double);
422
423 extern float __cdecl acosf (float);
424 extern long double __cdecl acosl (long double);
425
426 extern float __cdecl atanf (float);
427 extern long double __cdecl atanl (long double);
428
429 extern float __cdecl atan2f (float, float);
430 extern long double __cdecl atan2l (long double, long double);
431
432 /* 7.12.5 Hyperbolic functions: Double in C89 */
433 __CRT_INLINE float __cdecl sinhf (float x)
434 {return (float) sinh (x);}
435 extern long double __cdecl sinhl (long double);
436
437 __CRT_INLINE float __cdecl coshf (float x)
438 {return (float) cosh (x);}
439 extern long double __cdecl coshl (long double);
440
441 __CRT_INLINE float __cdecl tanhf (float x)
442 {return (float) tanh (x);}
443 extern long double __cdecl tanhl (long double);
444
445 /* Inverse hyperbolic trig functions */
446 /* 7.12.5.1 */
447 extern double __cdecl acosh (double);
448 extern float __cdecl acoshf (float);
449 extern long double __cdecl acoshl (long double);
450
451 /* 7.12.5.2 */
452 extern double __cdecl asinh (double);
453 extern float __cdecl asinhf (float);
454 extern long double __cdecl asinhl (long double);
455
456 /* 7.12.5.3 */
457 extern double __cdecl atanh (double);
458 extern float __cdecl atanf (float);
459 extern long double __cdecl atanhl (long double);
460
461 /* Exponentials and logarithms */
462 /* 7.12.6.1 Double in C89 */
463 __CRT_INLINE float __cdecl expf (float x)
464 {return (float) exp (x);}
465 extern long double __cdecl expl (long double);
466
467 /* 7.12.6.2 */
468 extern double __cdecl exp2(double);
469 extern float __cdecl exp2f(float);
470 extern long double __cdecl exp2l(long double);
471
472 /* 7.12.6.3 The expm1 functions */
473 /* TODO: These could be inlined */
474 extern double __cdecl expm1(double);
475 extern float __cdecl expm1f(float);
476 extern long double __cdecl expm1l(long double);
477
478 /* 7.12.6.4 Double in C89 */
479 __CRT_INLINE float __cdecl frexpf (float x, int* expn)
480 {return (float) frexp (x, expn);}
481 extern long double __cdecl frexpl (long double, int*);
482
483 /* 7.12.6.5 */
484 #define FP_ILOGB0 ((int)0x80000000)
485 #define FP_ILOGBNAN ((int)0x80000000)
486 extern int __cdecl ilogb (double);
487 extern int __cdecl ilogbf (float);
488 extern int __cdecl ilogbl (long double);
489
490 /* 7.12.6.6 Double in C89 */
491 __CRT_INLINE float __cdecl ldexpf (float x, int expn)
492 {return (float) ldexp (x, expn);}
493 extern long double __cdecl ldexpl (long double, int);
494
495 /* 7.12.6.7 Double in C89 */
496 extern float __cdecl logf (float);
497 extern long double __cdecl logl (long double);
498
499 /* 7.12.6.8 Double in C89 */
500 extern float __cdecl log10f (float);
501 extern long double __cdecl log10l (long double);
502
503 /* 7.12.6.9 */
504 extern double __cdecl log1p(double);
505 extern float __cdecl log1pf(float);
506 extern long double __cdecl log1pl(long double);
507
508 /* 7.12.6.10 */
509 extern double __cdecl log2 (double);
510 extern float __cdecl log2f (float);
511 extern long double __cdecl log2l (long double);
512
513 /* 7.12.6.11 */
514 extern double __cdecl logb (double);
515 extern float __cdecl logbf (float);
516 extern long double __cdecl logbl (long double);
517
518 /* Inline versions. GCC-4.0+ can do a better fast-math optimization
519 with __builtins. */
520 #if !(__MINGW_GNUC_PREREQ (4, 0) && defined __FAST_MATH__ )
521 __CRT_INLINE double __cdecl logb (double x)
522 {
523 double res;
524 __asm__ ("fxtract\n\t"
525 "fstp %%st" : "=t" (res) : "0" (x));
526 return res;
527 }
528
529 __CRT_INLINE float __cdecl logbf (float x)
530 {
531 float res;
532 __asm__ ("fxtract\n\t"
533 "fstp %%st" : "=t" (res) : "0" (x));
534 return res;
535 }
536
537 __CRT_INLINE long double __cdecl logbl (long double x)
538 {
539 long double res;
540 __asm__ ("fxtract\n\t"
541 "fstp %%st" : "=t" (res) : "0" (x));
542 return res;
543 }
544 #endif /* !defined __FAST_MATH__ || !__MINGW_GNUC_PREREQ (4, 0) */
545
546 /* 7.12.6.12 Double in C89 */
547 extern float __cdecl modff (float, float*);
548 extern long double __cdecl modfl (long double, long double*);
549
550 /* 7.12.6.13 */
551 extern double __cdecl scalbn (double, int);
552 extern float __cdecl scalbnf (float, int);
553 extern long double __cdecl scalbnl (long double, int);
554
555 extern double __cdecl scalbln (double, long);
556 extern float __cdecl scalblnf (float, long);
557 extern long double __cdecl scalblnl (long double, long);
558
559 /* 7.12.7.1 */
560 /* Implementations adapted from Cephes versions */
561 extern double __cdecl cbrt (double);
562 extern float __cdecl cbrtf (float);
563 extern long double __cdecl cbrtl (long double);
564
565 /* 7.12.7.2 The fabs functions: Double in C89 */
566 extern float __cdecl fabsf (float x);
567 extern long double __cdecl fabsl (long double x);
568
569 /* 7.12.7.3 */
570 extern double __cdecl hypot (double, double); /* in libmoldname.a */
571 __CRT_INLINE float __cdecl hypotf (float x, float y)
572 { return (float) hypot (x, y);}
573 extern long double __cdecl hypotl (long double, long double);
574
575 /* 7.12.7.4 The pow functions. Double in C89 */
576 __CRT_INLINE float __cdecl powf (float x, float y)
577 {return (float) pow (x, y);}
578 extern long double __cdecl powl (long double, long double);
579
580 /* 7.12.7.5 The sqrt functions. Double in C89. */
581 extern float __cdecl sqrtf (float);
582 extern long double __cdecl sqrtl (long double);
583
584 /* 7.12.8.1 The erf functions */
585 extern double __cdecl erf (double);
586 extern float __cdecl erff (float);
587 extern long double __cdecl erfl (long double);
588
589 /* 7.12.8.2 The erfc functions */
590 extern double __cdecl erfc (double);
591 extern float __cdecl erfcf (float);
592 extern long double __cdecl erfcl (long double);
593
594 /* 7.12.8.3 The lgamma functions */
595 extern double __cdecl lgamma (double);
596 extern float __cdecl lgammaf (float);
597 extern long double __cdecl lgammal (long double);
598
599 /* 7.12.8.4 The tgamma functions */
600 extern double __cdecl tgamma (double);
601 extern float __cdecl tgammaf (float);
602 extern long double __cdecl tgammal (long double);
603
604 /* 7.12.9.1 Double in C89 */
605 extern float __cdecl ceilf (float);
606 extern long double __cdecl ceill (long double);
607
608 /* 7.12.9.2 Double in C89 */
609 extern float __cdecl floorf (float);
610 extern long double __cdecl floorl (long double);
611
612 /* 7.12.9.3 */
613 extern double __cdecl nearbyint ( double);
614 extern float __cdecl nearbyintf (float);
615 extern long double __cdecl nearbyintl (long double);
616
617 /* 7.12.9.4 */
618 /* round, using fpu control word settings */
619 extern double __cdecl rint (double);
620 extern float __cdecl rintf (float);
621 extern long double __cdecl rintl (long double);
622
623 /* 7.12.9.5 */
624 extern long __cdecl lrint (double);
625 extern long __cdecl lrintf (float);
626 extern long __cdecl lrintl (long double);
627
628 extern long long __cdecl llrint (double);
629 extern long long __cdecl llrintf (float);
630 extern long long __cdecl llrintl (long double);
631
632 /* Inline versions of above.
633 GCC 4.0+ can do a better fast-math job with __builtins. */
634 #if !(__MINGW_GNUC_PREREQ (4, 0) && defined __FAST_MATH__ )
635 __CRT_INLINE double __cdecl rint (double x)
636 {
637 double retval;
638 __asm__ ("frndint;": "=t" (retval) : "0" (x));
639 return retval;
640 }
641
642 __CRT_INLINE float __cdecl rintf (float x)
643 {
644 float retval;
645 __asm__ ("frndint;" : "=t" (retval) : "0" (x) );
646 return retval;
647 }
648
649 __CRT_INLINE long double __cdecl rintl (long double x)
650 {
651 long double retval;
652 __asm__ ("frndint;" : "=t" (retval) : "0" (x) );
653 return retval;
654 }
655
656 __CRT_INLINE long __cdecl lrint (double x)
657 {
658 long retval;
659 __asm__ __volatile__
660 ("fistpl %0" : "=m" (retval) : "t" (x) : "st");
661 return retval;
662 }
663
664 __CRT_INLINE long __cdecl lrintf (float x)
665 {
666 long retval;
667 __asm__ __volatile__
668 ("fistpl %0" : "=m" (retval) : "t" (x) : "st");
669 return retval;
670 }
671
672 __CRT_INLINE long __cdecl lrintl (long double x)
673 {
674 long retval;
675 __asm__ __volatile__
676 ("fistpl %0" : "=m" (retval) : "t" (x) : "st");
677 return retval;
678 }
679
680 __CRT_INLINE long long __cdecl llrint (double x)
681 {
682 long long retval;
683 __asm__ __volatile__
684 ("fistpll %0" : "=m" (retval) : "t" (x) : "st");
685 return retval;
686 }
687
688 __CRT_INLINE long long __cdecl llrintf (float x)
689 {
690 long long retval;
691 __asm__ __volatile__
692 ("fistpll %0" : "=m" (retval) : "t" (x) : "st");
693 return retval;
694 }
695
696 __CRT_INLINE long long __cdecl llrintl (long double x)
697 {
698 long long retval;
699 __asm__ __volatile__
700 ("fistpll %0" : "=m" (retval) : "t" (x) : "st");
701 return retval;
702 }
703 #endif /* !__FAST_MATH__ || !__MINGW_GNUC_PREREQ (4,0) */
704
705 /* 7.12.9.6 */
706 /* round away from zero, regardless of fpu control word settings */
707 extern double __cdecl round (double);
708 extern float __cdecl roundf (float);
709 extern long double __cdecl roundl (long double);
710
711 /* 7.12.9.7 */
712 extern long __cdecl lround (double);
713 extern long __cdecl lroundf (float);
714 extern long __cdecl lroundl (long double);
715
716 extern long long __cdecl llround (double);
717 extern long long __cdecl llroundf (float);
718 extern long long __cdecl llroundl (long double);
719
720 /* 7.12.9.8 */
721 /* round towards zero, regardless of fpu control word settings */
722 extern double __cdecl trunc (double);
723 extern float __cdecl truncf (float);
724 extern long double __cdecl truncl (long double);
725
726 /* 7.12.10.1 Double in C89 */
727 extern float __cdecl fmodf (float, float);
728 extern long double __cdecl fmodl (long double, long double);
729
730 /* 7.12.10.2 */
731 extern double __cdecl remainder (double, double);
732 extern float __cdecl remainderf (float, float);
733 extern long double __cdecl remainderl (long double, long double);
734
735 /* 7.12.10.3 */
736 extern double __cdecl remquo(double, double, int *);
737 extern float __cdecl remquof(float, float, int *);
738 extern long double __cdecl remquol(long double, long double, int *);
739
740 /* 7.12.11.1 */
741 extern double __cdecl copysign (double, double); /* in libmoldname.a */
742 extern float __cdecl copysignf (float, float);
743 extern long double __cdecl copysignl (long double, long double);
744
745 /* 7.12.11.2 Return a NaN */
746 extern double __cdecl nan(const char *tagp);
747 extern float __cdecl nanf(const char *tagp);
748 extern long double __cdecl nanl(const char *tagp);
749
750 #ifndef __STRICT_ANSI__
751 #define _nan() nan("")
752 #define _nanf() nanf("")
753 #define _nanl() nanl("")
754 #endif
755
756 /* 7.12.11.3 */
757 extern double __cdecl nextafter (double, double); /* in libmoldname.a */
758 extern float __cdecl nextafterf (float, float);
759 extern long double __cdecl nextafterl (long double, long double);
760
761 /* 7.12.11.4 The nexttoward functions */
762 extern double __cdecl nexttoward (double, long double);
763 extern float __cdecl nexttowardf (float, long double);
764 extern long double __cdecl nexttowardl (long double, long double);
765
766 /* 7.12.12.1 */
767 /* x > y ? (x - y) : 0.0 */
768 extern double __cdecl fdim (double x, double y);
769 extern float __cdecl fdimf (float x, float y);
770 extern long double __cdecl fdiml (long double x, long double y);
771
772 /* fmax and fmin.
773 NaN arguments are treated as missing data: if one argument is a NaN
774 and the other numeric, then these functions choose the numeric
775 value. */
776
777 /* 7.12.12.2 */
778 extern double __cdecl fmax (double, double);
779 extern float __cdecl fmaxf (float, float);
780 extern long double __cdecl fmaxl (long double, long double);
781
782 /* 7.12.12.3 */
783 extern double __cdecl fmin (double, double);
784 extern float __cdecl fminf (float, float);
785 extern long double __cdecl fminl (long double, long double);
786
787 /* 7.12.13.1 */
788 /* return x * y + z as a ternary op */
789 extern double __cdecl fma (double, double, double);
790 extern float __cdecl fmaf (float, float, float);
791 extern long double __cdecl fmal (long double, long double, long double);
792
793
794 /* 7.12.14 */
795 /*
796 * With these functions, comparisons involving quiet NaNs set the FP
797 * condition code to "unordered". The IEEE floating-point spec
798 * dictates that the result of floating-point comparisons should be
799 * false whenever a NaN is involved, with the exception of the != op,
800 * which always returns true: yes, (NaN != NaN) is true).
801 */
802
803 #if __GNUC__ >= 3
804
805 #define isgreater(x, y) __builtin_isgreater(x, y)
806 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
807 #define isless(x, y) __builtin_isless(x, y)
808 #define islessequal(x, y) __builtin_islessequal(x, y)
809 #define islessgreater(x, y) __builtin_islessgreater(x, y)
810 #define isunordered(x, y) __builtin_isunordered(x, y)
811
812 #else
813 /* helper */
814 __CRT_INLINE int __cdecl
815 __fp_unordered_compare (long double x, long double y){
816 unsigned short retval;
817 __asm__ ("fucom %%st(1);"
818 "fnstsw;": "=a" (retval) : "t" (x), "u" (y));
819 return retval;
820 }
821
822 #define isgreater(x, y) ((__fp_unordered_compare(x, y) \
823 & 0x4500) == 0)
824 #define isless(x, y) ((__fp_unordered_compare (y, x) \
825 & 0x4500) == 0)
826 #define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \
827 & FP_INFINITE) == 0)
828 #define islessequal(x, y) ((__fp_unordered_compare(y, x) \
829 & FP_INFINITE) == 0)
830 #define islessgreater(x, y) ((__fp_unordered_compare(x, y) \
831 & FP_SUBNORMAL) == 0)
832 #define isunordered(x, y) ((__fp_unordered_compare(x, y) \
833 & 0x4500) == 0x4500)
834
835 #endif
836
837
838 #endif /* __STDC_VERSION__ >= 199901L */
839 #endif /* __NO_ISOCEXT */
840
841
842 #ifdef __cplusplus
843 }
844 #endif
845 #endif /* Not RC_INVOKED */
846
847
848 #endif /* Not _MATH_H_ */