math.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438
  1. /*
  2. * math.h
  3. *
  4. * Mathematical functions.
  5. *
  6. * This file is part of the Mingw32 package.
  7. *
  8. * Contributors:
  9. * Created by Colin Peters <[email protected]>
  10. *
  11. * THIS SOFTWARE IS NOT COPYRIGHTED
  12. *
  13. * This source code is offered for use in the public domain. You may
  14. * use, modify or distribute it freely.
  15. *
  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.
  20. *
  21. * $Revision: 1.2 $
  22. * $Author: bellard $
  23. * $Date: 2005/04/17 13:14:29 $
  24. *
  25. */
  26. #ifndef _MATH_H_
  27. #define _MATH_H_
  28. /* All the headers include this file. */
  29. #include <_mingw.h>
  30. /*
  31. * Types for the _exception structure.
  32. */
  33. #define _DOMAIN 1 /* domain error in argument */
  34. #define _SING 2 /* singularity */
  35. #define _OVERFLOW 3 /* range overflow */
  36. #define _UNDERFLOW 4 /* range underflow */
  37. #define _TLOSS 5 /* total loss of precision */
  38. #define _PLOSS 6 /* partial loss of precision */
  39. /*
  40. * Exception types with non-ANSI names for compatibility.
  41. */
  42. #ifndef __STRICT_ANSI__
  43. #ifndef _NO_OLDNAMES
  44. #define DOMAIN _DOMAIN
  45. #define SING _SING
  46. #define OVERFLOW _OVERFLOW
  47. #define UNDERFLOW _UNDERFLOW
  48. #define TLOSS _TLOSS
  49. #define PLOSS _PLOSS
  50. #endif /* Not _NO_OLDNAMES */
  51. #endif /* Not __STRICT_ANSI__ */
  52. /* These are also defined in Mingw float.h; needed here as well to work
  53. around GCC build issues. */
  54. #ifndef __STRICT_ANSI__
  55. #ifndef __MINGW_FPCLASS_DEFINED
  56. #define __MINGW_FPCLASS_DEFINED 1
  57. /* IEEE 754 classication */
  58. #define _FPCLASS_SNAN 0x0001 /* Signaling "Not a Number" */
  59. #define _FPCLASS_QNAN 0x0002 /* Quiet "Not a Number" */
  60. #define _FPCLASS_NINF 0x0004 /* Negative Infinity */
  61. #define _FPCLASS_NN 0x0008 /* Negative Normal */
  62. #define _FPCLASS_ND 0x0010 /* Negative Denormal */
  63. #define _FPCLASS_NZ 0x0020 /* Negative Zero */
  64. #define _FPCLASS_PZ 0x0040 /* Positive Zero */
  65. #define _FPCLASS_PD 0x0080 /* Positive Denormal */
  66. #define _FPCLASS_PN 0x0100 /* Positive Normal */
  67. #define _FPCLASS_PINF 0x0200 /* Positive Infinity */
  68. #endif /* __MINGW_FPCLASS_DEFINED */
  69. #endif /* Not __STRICT_ANSI__ */
  70. #ifndef RC_INVOKED
  71. #ifdef __cplusplus
  72. extern "C" {
  73. #endif
  74. /*
  75. * HUGE_VAL is returned by strtod when the value would overflow the
  76. * representation of 'double'. There are other uses as well.
  77. *
  78. * __imp__HUGE is a pointer to the actual variable _HUGE in
  79. * MSVCRT.DLL. If we used _HUGE directly we would get a pointer
  80. * to a thunk function.
  81. *
  82. * NOTE: The CRTDLL version uses _HUGE_dll instead.
  83. */
  84. #ifndef __DECLSPEC_SUPPORTED
  85. #ifdef __MSVCRT__
  86. extern double* __imp__HUGE;
  87. #define HUGE_VAL (*__imp__HUGE)
  88. #else
  89. /* CRTDLL */
  90. extern double* __imp__HUGE_dll;
  91. #define HUGE_VAL (*__imp__HUGE_dll)
  92. #endif
  93. #else /* __DECLSPEC_SUPPORTED */
  94. #ifdef __MSVCRT__
  95. __MINGW_IMPORT double _HUGE;
  96. #define HUGE_VAL _HUGE
  97. #else
  98. /* CRTDLL */
  99. __MINGW_IMPORT double _HUGE_dll;
  100. #define HUGE_VAL _HUGE_dll
  101. #endif
  102. #endif /* __DECLSPEC_SUPPORTED */
  103. struct _exception
  104. {
  105. int type;
  106. char *name;
  107. double arg1;
  108. double arg2;
  109. double retval;
  110. };
  111. double sin (double);
  112. double cos (double);
  113. double tan (double);
  114. double sinh (double);
  115. double cosh (double);
  116. double tanh (double);
  117. double asin (double);
  118. double acos (double);
  119. double atan (double);
  120. double atan2 (double, double);
  121. double exp (double);
  122. double log (double);
  123. double log10 (double);
  124. double pow (double, double);
  125. double sqrt (double);
  126. double ceil (double);
  127. double floor (double);
  128. double fabs (double);
  129. double ldexp (double, int);
  130. double frexp (double, int*);
  131. double modf (double, double*);
  132. double fmod (double, double);
  133. #ifndef __STRICT_ANSI__
  134. /* Complex number (for cabs) */
  135. struct _complex
  136. {
  137. double x; /* Real part */
  138. double y; /* Imaginary part */
  139. };
  140. double _cabs (struct _complex);
  141. double _hypot (double, double);
  142. double _j0 (double);
  143. double _j1 (double);
  144. double _jn (int, double);
  145. double _y0 (double);
  146. double _y1 (double);
  147. double _yn (int, double);
  148. int _matherr (struct _exception *);
  149. /* These are also declared in Mingw float.h; needed here as well to work
  150. around GCC build issues. */
  151. /* BEGIN FLOAT.H COPY */
  152. /*
  153. * IEEE recommended functions
  154. */
  155. double _chgsign (double);
  156. double _copysign (double, double);
  157. double _logb (double);
  158. double _nextafter (double, double);
  159. double _scalb (double, long);
  160. int _finite (double);
  161. int _fpclass (double);
  162. int _isnan (double);
  163. /* END FLOAT.H COPY */
  164. #if !defined (_NO_OLDNAMES) \
  165. || (defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L )
  166. /*
  167. * Non-underscored versions of non-ANSI functions. These reside in
  168. * liboldnames.a. They are now also ISO C99 standand names.
  169. * Provided for extra portability.
  170. */
  171. double cabs (struct _complex);
  172. double hypot (double, double);
  173. double j0 (double);
  174. double j1 (double);
  175. double jn (int, double);
  176. double y0 (double);
  177. double y1 (double);
  178. double yn (int, double);
  179. #endif /* Not _NO_OLDNAMES */
  180. #endif /* Not __STRICT_ANSI__ */
  181. #ifdef __cplusplus
  182. }
  183. #endif
  184. #endif /* Not RC_INVOKED */
  185. #ifndef __NO_ISOCEXT
  186. #define INFINITY HUGE_VAL
  187. #define NAN (0.0F/0.0F)
  188. /*
  189. Return values for fpclassify.
  190. These are based on Intel x87 fpu condition codes
  191. in the high byte of status word and differ from
  192. the return values for MS IEEE 754 extension _fpclass()
  193. */
  194. #define FP_NAN 0x0100
  195. #define FP_NORMAL 0x0400
  196. #define FP_INFINITE (FP_NAN | FP_NORMAL)
  197. #define FP_ZERO 0x4000
  198. #define FP_SUBNORMAL (FP_NORMAL | FP_ZERO)
  199. /* 0x0200 is signbit mask */
  200. #ifndef RC_INVOKED
  201. #ifdef __cplusplus
  202. extern "C" {
  203. #endif
  204. double nan(const char *tagp);
  205. float nanf(const char *tagp);
  206. #ifndef __STRICT_ANSI__
  207. #define nan() nan("")
  208. #define nanf() nanf("")
  209. #endif
  210. /*
  211. We can't inline float, because we want to ensure truncation
  212. to semantic type before classification. If we extend to long
  213. double, we will also need to make double extern only.
  214. (A normal long double value might become subnormal when
  215. converted to double, and zero when converted to float.)
  216. */
  217. extern __inline__ int __fpclassify (double x){
  218. unsigned short sw;
  219. __asm__ ("fxam; fstsw %%ax;" : "=a" (sw): "t" (x));
  220. return sw & (FP_NAN | FP_NORMAL | FP_ZERO );
  221. }
  222. extern int __fpclassifyf (float);
  223. #define fpclassify(x) ((sizeof(x) == sizeof(float)) ? __fpclassifyf(x) \
  224. : __fpclassify(x))
  225. /* We don't need to worry about trucation here:
  226. A NaN stays a NaN. */
  227. extern __inline__ int __isnan (double _x)
  228. {
  229. unsigned short sw;
  230. __asm__ ("fxam;"
  231. "fstsw %%ax": "=a" (sw) : "t" (_x));
  232. return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
  233. == FP_NAN;
  234. }
  235. extern __inline__ int __isnanf (float _x)
  236. {
  237. unsigned short sw;
  238. __asm__ ("fxam;"
  239. "fstsw %%ax": "=a" (sw) : "t" (_x));
  240. return (sw & (FP_NAN | FP_NORMAL | FP_INFINITE | FP_ZERO | FP_SUBNORMAL))
  241. == FP_NAN;
  242. }
  243. #define isnan(x) ((sizeof(x) == sizeof(float)) ? __isnanf(x) \
  244. : __isnan(x))
  245. #define isfinite(x) ((fpclassify(x) & FP_NAN) == 0)
  246. #define isinf(x) (fpclassify(x) == FP_INFINITE)
  247. #define isnormal(x) (fpclassify(x) == FP_NORMAL)
  248. extern __inline__ int __signbit (double x) {
  249. unsigned short stw;
  250. __asm__ ( "fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
  251. return stw & 0x0200;
  252. }
  253. extern __inline__ int __signbitf (float x) {
  254. unsigned short stw;
  255. __asm__ ("fxam; fstsw %%ax;": "=a" (stw) : "t" (x));
  256. return stw & 0x0200;
  257. }
  258. #define signbit(x) ((sizeof(x) == sizeof(float)) ? __signbitf(x) \
  259. : __signbit(x))
  260. /*
  261. * With these functions, comparisons involving quiet NaNs set the FP
  262. * condition code to "unordered". The IEEE floating-point spec
  263. * dictates that the result of floating-point comparisons should be
  264. * false whenever a NaN is involved, with the exception of the !=,
  265. * which always returns true.
  266. */
  267. #if __GNUC__ >= 3
  268. #define isgreater(x, y) __builtin_isgreater(x, y)
  269. #define isgreaterequal(x, y) __builtin_isgreaterequal(x, y)
  270. #define isless(x, y) __builtin_isless(x, y)
  271. #define islessequal(x, y) __builtin_islessequal(x, y)
  272. #define islessgreater(x, y) __builtin_islessgreater(x, y)
  273. #define isunordered(x, y) __builtin_isunordered(x, y)
  274. #else
  275. /* helper */
  276. extern __inline__ int __fp_unordered_compare (double x, double y){
  277. unsigned short retval;
  278. __asm__ ("fucom %%st(1);"
  279. "fnstsw;": "=a" (retval) : "t" (x), "u" (y));
  280. return retval;
  281. }
  282. #define isgreater(x, y) ((__fp_unordered_compare(x, y) \
  283. & 0x4500) == 0)
  284. #define isless(x, y) ((__fp_unordered_compare (y, x) \
  285. & 0x4500) == 0)
  286. #define isgreaterequal(x, y) ((__fp_unordered_compare (x, y) \
  287. & FP_INFINITE) == 0)
  288. #define islessequal(x, y) ((__fp_unordered_compare(y, x) \
  289. & FP_INFINITE) == 0)
  290. #define islessgreater(x, y) ((__fp_unordered_compare(x, y) \
  291. & FP_SUBNORMAL) == 0)
  292. #define isunordered(x, y) ((__fp_unordered_compare(x, y) \
  293. & 0x4500) == 0x4500)
  294. #endif
  295. /* round, using fpu control word settings */
  296. extern __inline__ double rint (double x)
  297. {
  298. double retval;
  299. __asm__ ("frndint;": "=t" (retval) : "0" (x));
  300. return retval;
  301. }
  302. extern __inline__ float rintf (float x)
  303. {
  304. float retval;
  305. __asm__ ("frndint;" : "=t" (retval) : "0" (x) );
  306. return retval;
  307. }
  308. /* round away from zero, regardless of fpu control word settings */
  309. extern double round (double);
  310. extern float roundf (float);
  311. /* round towards zero, regardless of fpu control word settings */
  312. extern double trunc (double);
  313. extern float truncf (float);
  314. /* fmax and fmin.
  315. NaN arguments are treated as missing data: if one argument is a NaN and the other numeric, then the
  316. these functions choose the numeric value.
  317. */
  318. extern double fmax (double, double);
  319. extern double fmin (double, double);
  320. extern float fmaxf (float, float);
  321. float fminf (float, float);
  322. /* return x * y + z as a ternary op */
  323. extern double fma (double, double, double);
  324. extern float fmaf (float, float, float);
  325. /* one lonely transcendental */
  326. extern double log2 (double _x);
  327. extern float log2f (float _x);
  328. /* The underscored versions are in MSVCRT.dll.
  329. The stubs for these are in libmingwex.a */
  330. double copysign (double, double);
  331. float copysignf (float, float);
  332. double logb (double);
  333. float logbf (float);
  334. double nextafter (double, double);
  335. float nextafterf (float, float);
  336. double scalb (double, long);
  337. float scalbf (float, long);
  338. #if !defined (__STRICT_ANSI__) /* inline using non-ANSI functions */
  339. extern __inline__ double copysign (double x, double y)
  340. { return _copysign(x, y); }
  341. extern __inline__ float copysignf (float x, float y)
  342. { return _copysign(x, y); }
  343. extern __inline__ double logb (double x)
  344. { return _logb(x); }
  345. extern __inline__ float logbf (float x)
  346. { return _logb(x); }
  347. extern __inline__ double nextafter(double x, double y)
  348. { return _nextafter(x, y); }
  349. extern __inline__ float nextafterf(float x, float y)
  350. { return _nextafter(x, y); }
  351. extern __inline__ double scalb (double x, long i)
  352. { return _scalb (x, i); }
  353. extern __inline__ float scalbf (float x, long i)
  354. { return _scalb(x, i); }
  355. #endif /* (__STRICT_ANSI__) */
  356. #ifdef __cplusplus
  357. }
  358. #endif
  359. #endif /* Not RC_INVOKED */
  360. #endif /* __NO_ISOCEXT */
  361. #endif /* Not _MATH_H_ */