|
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 truncation 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 atanhf (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_ */ |