4 * Mathematical functions.
6 * This file is part of the Mingw32 package.
9 * Created by Colin Peters <colin@bird.fu.is.saga-u.ac.jp>
11 * THIS SOFTWARE IS NOT COPYRIGHTED
13 * This source code is offered for use in the public domain. You may
14 * use, modify or distribute it freely.
16 * This code is distributed in the hope that it will be useful but
17 * WITHOUT ANY WARRANTY. ALL WARRANTIES, EXPRESS OR IMPLIED ARE HEREBY
18 * DISCLAIMED. This includes but is not limited to warranties of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23 * $Date: 2005/04/17 13:14:29 $
30 /* All the headers include this file. */
34 * Types for the _exception structure.
37 #define _DOMAIN 1 /* domain error in argument */
38 #define _SING 2 /* singularity */
39 #define _OVERFLOW 3 /* range overflow */
40 #define _UNDERFLOW 4 /* range underflow */
41 #define _TLOSS 5 /* total loss of precision */
42 #define _PLOSS 6 /* partial loss of precision */
45 * Exception types with non-ANSI names for compatibility.
48 #ifndef __STRICT_ANSI__
51 #define DOMAIN _DOMAIN
53 #define OVERFLOW _OVERFLOW
54 #define UNDERFLOW _UNDERFLOW
58 #endif /* Not _NO_OLDNAMES */
59 #endif /* Not __STRICT_ANSI__ */
62 /* These are also defined in Mingw float.h; needed here as well to work
63 around GCC build issues. */
64 #ifndef __STRICT_ANSI__
65 #ifndef __MINGW_FPCLASS_DEFINED
66 #define __MINGW_FPCLASS_DEFINED 1
67 /* IEEE 754 classication */
68 #define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
69 #define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
70 #define _FPCLASS_NINF 0x0004 /* Negative Infinity */
71 #define _FPCLASS_NN 0x0008 /* Negative Normal */
72 #define _FPCLASS_ND 0x0010 /* Negative Denormal */
73 #define _FPCLASS_NZ 0x0020 /* Negative Zero */
74 #define _FPCLASS_PZ 0x0040 /* Positive Zero */
75 #define _FPCLASS_PD 0x0080 /* Positive Denormal */
76 #define _FPCLASS_PN 0x0100 /* Positive Normal */
77 #define _FPCLASS_PINF 0x0200 /* Positive Infinity */
78 #endif /* __MINGW_FPCLASS_DEFINED */
79 #endif /* Not __STRICT_ANSI__ */
88 * HUGE_VAL is returned by strtod when the value would overflow the
89 * representation of 'double'. There are other uses as well.
91 * __imp__HUGE is a pointer to the actual variable _HUGE in
92 * MSVCRT.DLL. If we used _HUGE directly we would get a pointer
93 * to a thunk function.
95 * NOTE: The CRTDLL version uses _HUGE_dll instead.
98 #ifndef __DECLSPEC_SUPPORTED
101 extern double* __imp__HUGE
;
102 #define HUGE_VAL (*__imp__HUGE)
105 extern double* __imp__HUGE_dll
;
106 #define HUGE_VAL (*__imp__HUGE_dll)
109 #else /* __DECLSPEC_SUPPORTED */
112 __MINGW_IMPORT
double _HUGE
;
113 #define HUGE_VAL _HUGE
116 __MINGW_IMPORT
double _HUGE_dll
;
117 #define HUGE_VAL _HUGE_dll
120 #endif /* __DECLSPEC_SUPPORTED */
135 double sinh (double);
136 double cosh (double);
137 double tanh (double);
138 double asin (double);
139 double acos (double);
140 double atan (double);
141 double atan2 (double, double);
144 double log10 (double);
145 double pow (double, double);
146 double sqrt (double);
147 double ceil (double);
148 double floor (double);
149 double fabs (double);
150 double ldexp (double, int);
151 double frexp (double, int*);
152 double modf (double, double*);
153 double fmod (double, double);
156 #ifndef __STRICT_ANSI__
158 /* Complex number (for cabs) */
161 double x
; /* Real part */
162 double y
; /* Imaginary part */
165 double _cabs (struct _complex
);
166 double _hypot (double, double);
169 double _jn (int, double);
172 double _yn (int, double);
173 int _matherr (struct _exception
*);
175 /* These are also declared in Mingw float.h; needed here as well to work
176 around GCC build issues. */
177 /* BEGIN FLOAT.H COPY */
179 * IEEE recommended functions
182 double _chgsign (double);
183 double _copysign (double, double);
184 double _logb (double);
185 double _nextafter (double, double);
186 double _scalb (double, long);
188 int _finite (double);
189 int _fpclass (double);
192 /* END FLOAT.H COPY */
194 #if !defined (_NO_OLDNAMES) \
195 || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
198 * Non-underscored versions of non-ANSI functions. These reside in
199 * liboldnames.a. They are now also ISO C99 standand names.
200 * Provided for extra portability.
203 double cabs (struct _complex
);
204 double hypot (double, double);
207 double jn (int, double);
210 double yn (int, double);
212 #endif /* Not _NO_OLDNAMES */
214 #endif /* Not __STRICT_ANSI__ */
219 #endif /* Not RC_INVOKED */
224 #define INFINITY HUGE_VAL
225 #define NAN (0.0F/0.0F)
228 Return values for fpclassify.
229 These are based on Intel x87 fpu condition codes
230 in the high byte of status word and differ from
231 the return values for MS IEEE 754 extension _fpclass()
233 #define FP_NAN 0x0100
234 #define FP_NORMAL 0x0400
235 #define FP_INFINITE (FP_NAN | FP_NORMAL)
236 #define FP_ZERO 0x4000
237 #define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
238 /* 0x0200 is signbit mask */
245 double nan(const char *tagp
);
246 float nanf(const char *tagp
);
248 #ifndef __STRICT_ANSI__
249 #define nan() nan("")
250 #define nanf() nanf("")
255 We can't inline float, because we want to ensure truncation
256 to semantic type before classification. If we extend to long
257 double, we will also need to make double extern only.
258 (A normal long double value might become subnormal when
259 converted to double, and zero when converted to float.)
261 extern __inline__
int __fpclassify (double x
){
263 __asm__ ("fxam; fstsw %%ax;" : "=a" (sw
): "t" (x
));
264 return sw
& (FP_NAN
| FP_NORMAL
| FP_ZERO
);
267 extern int __fpclassifyf (float);
269 #define fpclassify(x) ((sizeof(x) == sizeof(float)) ? __fpclassifyf(x) \
272 /* We don't need to worry about trucation here:
273 A NaN stays a NaN. */
275 extern __inline__
int __isnan (double _x
)
279 "fstsw %%ax": "=a" (sw
) : "t" (_x
));
280 return (sw
& (FP_NAN
| FP_NORMAL
| FP_INFINITE
| FP_ZERO
| FP_SUBNORMAL
))
284 extern __inline__
int __isnanf (float _x
)
288 "fstsw %%ax": "=a" (sw
) : "t" (_x
));
289 return (sw
& (FP_NAN
| FP_NORMAL
| FP_INFINITE
| FP_ZERO
| FP_SUBNORMAL
))
293 #define isnan(x) ((sizeof(x) == sizeof(float)) ? __isnanf(x) \
297 #define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
298 #define isinf(x) (fpclassify(x) == FP_INFINITE)
299 #define isnormal(x) (fpclassify(x) == FP_NORMAL)
302 extern __inline__
int __signbit (double x
) {
304 __asm__ ( "fxam; fstsw %%ax;": "=a" (stw
) : "t" (x
));
308 extern __inline__
int __signbitf (float x
) {
310 __asm__ ("fxam; fstsw %%ax;": "=a" (stw
) : "t" (x
));
314 #define signbit(x) ((sizeof(x) == sizeof(float)) ? __signbitf(x) \
317 * With these functions, comparisons involving quiet NaNs set the FP
318 * condition code to "unordered". The IEEE floating-point spec
319 * dictates that the result of floating-point comparisons should be
320 * false whenever a NaN is involved, with the exception of the !=,
321 * which always returns true.
326 #define isgreater(x, y) __builtin_isgreater(x, y)
327 #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
328 #define isless(x, y) __builtin_isless(x, y)
329 #define islessequal(x, y) __builtin_islessequal(x, y)
330 #define islessgreater(x, y) __builtin_islessgreater(x, y)
331 #define isunordered(x, y) __builtin_isunordered(x, y)
335 extern __inline__
int __fp_unordered_compare (double x
, double y
){
336 unsigned short retval
;
337 __asm__ ("fucom %%st(1);"
338 "fnstsw;": "=a" (retval
) : "t" (x
), "u" (y
));
342 #define isgreater(x, y) ((__fp_unordered_compare(x, y) \
344 #define isless(x, y) ((__fp_unordered_compare (y, x) \
346 #define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \
348 #define islessequal(x, y) ((__fp_unordered_compare(y, x) \
350 #define islessgreater(x, y) ((__fp_unordered_compare(x, y) \
351 & FP_SUBNORMAL) == 0)
352 #define isunordered(x, y) ((__fp_unordered_compare(x, y) \
357 /* round, using fpu control word settings */
358 extern __inline__
double rint (double x
)
361 __asm__ ("frndint;": "=t" (retval
) : "0" (x
));
365 extern __inline__
float rintf (float x
)
368 __asm__ ("frndint;" : "=t" (retval
) : "0" (x
) );
372 /* round away from zero, regardless of fpu control word settings */
373 extern double round (double);
374 extern float roundf (float);
376 /* round towards zero, regardless of fpu control word settings */
377 extern double trunc (double);
378 extern float truncf (float);
382 NaN arguments are treated as missing data: if one argument is a NaN and the other numeric, then the
383 these functions choose the numeric value.
386 extern double fmax (double, double);
387 extern double fmin (double, double);
388 extern float fmaxf (float, float);
389 float fminf (float, float);
391 /* return x * y + z as a ternary op */
392 extern double fma (double, double, double);
393 extern float fmaf (float, float, float);
395 /* one lonely transcendental */
396 extern double log2 (double _x
);
397 extern float log2f (float _x
);
399 /* The underscored versions are in MSVCRT.dll.
400 The stubs for these are in libmingwex.a */
402 double copysign (double, double);
403 float copysignf (float, float);
404 double logb (double);
406 double nextafter (double, double);
407 float nextafterf (float, float);
408 double scalb (double, long);
409 float scalbf (float, long);
411 #if !defined (__STRICT_ANSI__) /* inline using non-ANSI functions */
412 extern __inline__
double copysign (double x
, double y
)
413 { return _copysign(x
, y
); }
414 extern __inline__
float copysignf (float x
, float y
)
415 { return _copysign(x
, y
); }
416 extern __inline__
double logb (double x
)
418 extern __inline__
float logbf (float x
)
420 extern __inline__
double nextafter(double x
, double y
)
421 { return _nextafter(x
, y
); }
422 extern __inline__
float nextafterf(float x
, float y
)
423 { return _nextafter(x
, y
); }
424 extern __inline__
double scalb (double x
, long i
)
425 { return _scalb (x
, i
); }
426 extern __inline__
float scalbf (float x
, long i
)
427 { return _scalb(x
, i
); }
428 #endif /* (__STRICT_ANSI__) */
433 #endif /* Not RC_INVOKED */
435 #endif /* __NO_ISOCEXT */
437 #endif /* Not _MATH_H_ */