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