Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members

fxmath.h
1 /********************************************************************************
2 * *
3 * M a t h F u n c t i o n s *
4 * *
5 *********************************************************************************
6 * Copyright (C) 2015,2017 by Jeroen van der Zijp. All Rights Reserved. *
7 *********************************************************************************
8 * This library is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU Lesser General Public License as published by *
10 * the Free Software Foundation; either version 3 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This library is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU Lesser General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU Lesser General Public License *
19 * along with this program. If not, see <http://www.gnu.org/licenses/> *
20 ********************************************************************************/
21 #ifndef FXMATH_H
22 #define FXMATH_H
23 
24 // Remove macros
25 #undef fabs
26 #undef fabsf
27 #undef fmod
28 #undef fmodf
29 
30 #undef ceil
31 #undef ceilf
32 #undef floor
33 #undef floorf
34 #undef round
35 #undef roundf
36 #undef trunc
37 #undef truncf
38 #undef nearbyint
39 #undef nearbyintf
40 #undef rint
41 #undef rintf
42 
43 #undef sin
44 #undef sinf
45 #undef cos
46 #undef cosf
47 #undef tan
48 #undef tanf
49 #undef asin
50 #undef asinf
51 #undef acos
52 #undef acosf
53 #undef atan
54 #undef atanf
55 #undef atan2
56 #undef atan2f
57 #undef sinh
58 #undef sinhf
59 #undef cosh
60 #undef coshf
61 #undef tanh
62 #undef tanhf
63 #undef asinh
64 #undef asinhf
65 #undef acosh
66 #undef acoshf
67 #undef atanh
68 #undef atanhf
69 
70 #undef pow
71 #undef powf
72 #undef exp
73 #undef expf
74 #undef exp2
75 #undef exp2f
76 #undef exp10
77 #undef exp10f
78 #undef log
79 #undef logf
80 #undef log1p
81 #undef log1pf
82 #undef log2
83 #undef log2f
84 #undef log10
85 #undef log10f
86 
87 #undef sqrt
88 #undef sqrtf
89 #undef cbrt
90 #undef cbrtf
91 #undef sqr
92 #undef sqrf
93 #undef cub
94 #undef cubf
95 
96 #undef fmax
97 #undef fmaxf
98 #undef fmin
99 #undef fminf
100 #undef copysign
101 #undef copysignf
102 
103 // Switch on remedial math on Windows with VC++
104 #if defined(WIN32) && (defined(_MSC_VER) || defined(__MINGW32__))
105 #define NO_CEILF
106 #define NO_FLOORF
107 #define NO_ROUNDF
108 #define NO_ROUND
109 #define NO_TRUNCF
110 #define NO_TRUNC
111 #define NO_NEARBYINTF
112 #define NO_NEARBYINT
113 #define NO_RINTF
114 #define NO_RINT
115 #define NO_EXPM1F
116 #define NO_EXPM1
117 #define NO_EXP2F
118 #define NO_EXP2
119 #define NO_EXP10F
120 #define NO_EXP10
121 #define NO_LOG1PF
122 #define NO_LOG1P
123 #define NO_LOG2F
124 #define NO_LOG2
125 #define NO_CBRTF
126 #define NO_CBRT
127 #define NO_SINHF
128 #define NO_SINH
129 #define NO_COSHF
130 #define NO_COSH
131 #define NO_TANHF
132 #define NO_TANH
133 #define NO_ASINHF
134 #define NO_ASINH
135 #define NO_ACOSHF
136 #define NO_ACOSH
137 #define NO_ATANHF
138 #define NO_ATANH
139 #define NO_FMAXF
140 #define NO_FMAX
141 #define NO_FMINF
142 #define NO_FMIN
143 #define NO_COPYSIGNF
144 #define NO_COPYSIGN
145 #endif
146 
147 // Systems below are missing these functions
148 #if defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
149 #define NO_EXP10F
150 #define NO_EXP10
151 #endif
152 
153 namespace FX {
154 
155 /********************************* Constants *********************************/
156 
158 const FXdouble PI=3.1415926535897932384626433833;
159 
161 const FXdouble EULER=2.7182818284590452353602874713;
162 
164 const FXdouble DTOR=0.0174532925199432957692369077;
165 
167 const FXdouble RTOD=57.295779513082320876798154814;
168 
169 /********************************* Functions *********************************/
170 
171 // FOX math functions live here
172 namespace Math {
173 
174 
176 static inline FXuint fpSign(FXfloat x){
177  union{ FXfloat f; FXuint u; } z={x}; return (z.u>>31);
178  }
179 
181 static inline FXulong fpSign(FXdouble x){
182  union{ FXdouble f; FXulong u; } z={x}; return (z.u>>63);
183  }
184 
185 
187 static inline FXuint fpMantissa(FXfloat x){
188  union{ FXfloat f; FXuint u; } z={x}; return (z.u&0x007fffff);
189  }
190 
192 static inline FXulong fpMantissa(FXdouble x){
193  union{ FXdouble f; FXulong u; } z={x}; return (z.u&FXULONG(0x000fffffffffffff));
194  }
195 
196 
198 static inline FXuint fpExponent(FXfloat x){
199  union{ FXfloat f; FXuint u; } z={x}; return ((z.u>>23)&0xff);
200  }
201 
203 static inline FXulong fpExponent(FXdouble x){
204  union{ FXdouble f; FXulong u; } z={x}; return ((z.u>>52)&0x7ff);
205  }
206 
207 
209 static inline FXbool fpFinite(FXfloat x){
210  union{ FXfloat f; FXuint u; } z={x}; return ((z.u&0x7fffffff)<0x7f800000);
211  }
212 
214 static inline FXbool fpFinite(FXdouble x){
215  union{ FXdouble f; FXulong u; } z={x}; return ((z.u&FXULONG(0x7fffffffffffffff))<FXULONG(0x7ff0000000000000));
216  }
217 
218 
220 static inline FXbool fpInfinite(FXfloat x){
221  union{ FXfloat f; FXuint u; } z={x}; return ((z.u&0x7fffffff)==0x7f800000);
222  }
223 
225 static inline FXbool fpInfinite(FXdouble x){
226  union{ FXdouble f; FXulong u; } z={x}; return ((z.u&FXULONG(0x7fffffffffffffff))==FXULONG(0x7ff0000000000000));
227  }
228 
229 
231 static inline FXbool fpNan(FXfloat x){
232  union{ FXfloat f; FXuint u; } z={x}; return (0x7f800000<(z.u&0x7fffffff));
233  }
234 
236 static inline FXbool fpNan(FXdouble x){
237  union{ FXdouble f; FXulong u; } z={x}; return (FXULONG(0x7ff0000000000000)<(z.u&FXULONG(0x7fffffffffffffff)));
238  }
239 
240 
242 static inline FXbool fpNormal(FXfloat x){
243  union{ FXfloat f; FXuint u; } z={x};
244  return ((z.u&0x7fffffff)==0) || ((0x00800000<=(z.u&0x7fffffff)) && ((z.u&0x7fffffff)<0x7f800000));
245  }
246 
248 static inline FXbool fpNormal(FXdouble x){
249  union{ FXdouble f; FXulong u; } z={x};
250  return ((z.u&FXULONG(0x7fffffffffffffff))==0) || ((FXULONG(0x0010000000000000)<=(z.u&FXULONG(0x7fffffffffffffff))) && ((z.u&FXULONG(0x7fffffffffffffff))<FXULONG(0x7ff0000000000000)));
251  }
252 
253 
255 #if defined(NO_FABSF)
256 static inline FXfloat fabs(FXfloat x){ return (x<0.0f) ? -x : x; }
257 #else
258 static inline FXfloat fabs(FXfloat x){ return ::fabsf(x); }
259 #endif
260 
262 static inline FXdouble fabs(FXdouble x){ return ::fabs(x); }
263 
264 
266 static inline FXfloat fmod(FXfloat x,FXfloat y){ return ::fmodf(x,y); }
267 
269 static inline FXdouble fmod(FXdouble x,FXdouble y){ return ::fmod(x,y); }
270 
271 
272 
274 #if defined(NO_CEILF)
275 extern FXAPI FXfloat ceil(FXfloat x);
276 #else
277 static inline FXfloat ceil(FXfloat x){ return ::ceilf(x); }
278 #endif
279 
281 static inline FXdouble ceil(FXdouble x){ return ::ceil(x); }
282 
283 
285 #if defined(NO_FLOORF)
286 extern FXAPI FXfloat floor(FXfloat x);
287 #else
288 static inline FXfloat floor(FXfloat x){ return ::floorf(x); }
289 #endif
290 
292 static inline FXdouble floor(FXdouble x){ return ::floor(x); }
293 
295 #if defined(NO_ROUNDF)
296 extern FXAPI FXfloat round(FXfloat x);
297 #else
298 static inline FXfloat round(FXfloat x){ return ::roundf(x); }
299 #endif
300 
302 #if defined(NO_ROUND)
303 extern FXAPI FXdouble round(FXdouble x);
304 #else
305 static inline FXdouble round(FXdouble x){ return ::round(x); }
306 #endif
307 
308 
310 #if defined(NO_TRUNCF)
311 extern FXAPI FXfloat trunc(FXfloat x);
312 #else
313 static inline FXfloat trunc(FXfloat x){ return ::truncf(x); }
314 #endif
315 
317 #if defined(NO_TRUNC)
318 extern FXAPI FXdouble trunc(FXdouble x);
319 #else
320 static inline FXdouble trunc(FXdouble x){ return ::trunc(x); }
321 #endif
322 
324 #if defined(NO_NEARBYINTF)
325 extern FXAPI FXfloat nearbyint(FXfloat x);
326 #else
327 static inline FXfloat nearbyint(FXfloat x){ return ::nearbyintf(x); }
328 #endif
329 
331 #if defined(NO_NEARBYINT)
332 extern FXAPI FXdouble nearbyint(FXdouble x);
333 #else
334 static inline FXdouble nearbyint(FXdouble x){ return ::nearbyint(x); }
335 #endif
336 
338 #if defined(NO_RINTF)
339 extern FXAPI FXfloat rint(FXfloat x);
340 #else
341 static inline FXfloat rint(FXfloat x){ return ::rintf(x); }
342 #endif
343 
345 #if defined(NO_RINT)
346 extern FXAPI FXdouble rint(FXdouble x);
347 #else
348 static inline FXdouble rint(FXdouble x){ return ::rint(x); }
349 #endif
350 
352 static inline FXfloat sin(FXfloat x){ return ::sinf(x); }
353 
355 static inline FXdouble sin(FXdouble x){ return ::sin(x); }
356 
357 
359 static inline FXfloat cos(FXfloat x){ return ::cosf(x); }
360 
362 static inline FXdouble cos(FXdouble x){ return ::cos(x); }
363 
364 
366 static inline FXfloat tan(FXfloat x){ return ::tanf(x); }
367 
369 static inline FXdouble tan(FXdouble x){ return ::tan(x); }
370 
371 
373 static inline FXfloat asin(FXfloat x){ return ::asinf(x); }
374 
376 static inline FXdouble asin(FXdouble x){ return ::asin(x); }
377 
378 
380 static inline FXfloat acos(FXfloat x){ return ::acosf(x); }
381 
383 static inline FXdouble acos(FXdouble x){ return ::acos(x); }
384 
385 
387 static inline FXfloat atan(FXfloat x){ return ::atanf(x); }
388 
390 static inline FXdouble atan(FXdouble x){ return ::atan(x); }
391 
392 
394 static inline FXfloat atan2(FXfloat y,FXfloat x){ return ::atan2f(y,x); }
395 
397 static inline FXdouble atan2(FXdouble y,FXdouble x){ return ::atan2(y,x); }
398 
399 
401 #if defined(NO_SINHF)
402 extern FXAPI FXfloat sinh(FXfloat x);
403 #else
404 static inline FXfloat sinh(FXfloat x){ return ::sinhf(x); }
405 #endif
406 
408 #if defined(NO_SINH)
409 extern FXAPI FXdouble sinh(FXdouble x);
410 #else
411 static inline FXdouble sinh(FXdouble x){ return ::sinh(x); }
412 #endif
413 
414 
416 #if defined(NO_COSHF)
417 extern FXAPI FXfloat cosh(FXfloat x);
418 #else
419 static inline FXfloat cosh(FXfloat x){ return ::coshf(x); }
420 #endif
421 
423 #if defined(NO_COSH)
424 extern FXAPI FXdouble cosh(FXdouble x);
425 #else
426 static inline FXdouble cosh(FXdouble x){ return ::cosh(x); }
427 #endif
428 
429 
431 #if defined(NO_TANHF)
432 extern FXAPI FXfloat tanh(FXfloat x);
433 #else
434 static inline FXfloat tanh(FXfloat x){ return ::tanhf(x); }
435 #endif
436 
438 #if defined(NO_TANH)
439 extern FXAPI FXdouble tanh(FXdouble x);
440 #else
441 static inline FXdouble tanh(FXdouble x){ return ::tanh(x); }
442 #endif
443 
444 
446 #if defined(NO_ASINHF)
447 extern FXAPI FXfloat asinh(FXfloat x);
448 #else
449 static inline FXfloat asinh(FXfloat x){ return ::asinhf(x); }
450 #endif
451 
453 #if defined(NO_ASINH)
454 extern FXAPI FXdouble asinh(FXdouble x);
455 #else
456 static inline FXdouble asinh(FXdouble x){ return ::asinh(x); }
457 #endif
458 
459 
461 #if defined(NO_ACOSHF)
462 extern FXAPI FXfloat acosh(FXfloat x);
463 #else
464 static inline FXfloat acosh(FXfloat x){ return ::acoshf(x); }
465 #endif
466 
468 #if defined(NO_ACOSH)
469 extern FXAPI FXdouble acosh(FXdouble x);
470 #else
471 static inline FXdouble acosh(FXdouble x){ return ::acosh(x); }
472 #endif
473 
474 
476 #if defined(NO_ATANHF)
477 extern FXAPI FXfloat atanh(FXfloat x);
478 #else
479 static inline FXfloat atanh(FXfloat x){ return ::atanhf(x); }
480 #endif
481 
483 #if defined(NO_ATANH)
484 extern FXAPI FXdouble atanh(FXdouble x);
485 #else
486 static inline FXdouble atanh(FXdouble x){ return ::atanh(x); }
487 #endif
488 
489 
491 static inline FXfloat pow(FXfloat x,FXfloat y){ return ::powf(x,y); }
492 
494 static inline FXdouble pow(FXdouble x,FXdouble y){ return ::pow(x,y); }
495 
496 
498 static inline FXfloat exp(FXfloat x){ return ::expf(x); }
499 
501 static inline FXdouble exp(FXdouble x){ return ::exp(x); }
502 
503 
505 #if defined(NO_EXPM1F)
506 static inline FXfloat expm1(FXfloat x){ return ::expf(x)-1.0f; }
507 #else
508 static inline FXfloat expm1(FXfloat x){ return ::expm1f(x); }
509 #endif
510 
512 #if defined(NO_EXPM1)
513 static inline FXdouble expm1(FXdouble x){ return ::exp(x)-1.0; }
514 #else
515 static inline FXdouble expm1(FXdouble x){ return ::expm1(x); }
516 #endif
517 
518 
520 #if defined(NO_EXP2F)
521 static inline FXfloat exp2(FXfloat x){ return Math::pow(2.0f,x); }
522 #else
523 static inline FXfloat exp2(FXfloat x){ return ::exp2f(x); }
524 #endif
525 
527 #if defined(NO_EXP2)
528 static inline FXdouble exp2(FXdouble x){ return Math::pow(2.0,x); }
529 #else
530 static inline FXdouble exp2(FXdouble x){ return ::exp2(x); }
531 #endif
532 
533 
535 #if defined(NO_EXP10F)
536 static inline FXfloat exp10(FXfloat x){ return Math::pow(10.0f,x); }
537 #else
538 static inline FXfloat exp10(FXfloat x){ return ::exp10f(x); }
539 #endif
540 
542 #if defined(NO_EXP10)
543 static inline FXdouble exp10(FXdouble x){ return Math::pow(10.0,x); }
544 #else
545 static inline FXdouble exp10(FXdouble x){ return ::exp10(x); }
546 #endif
547 
548 
550 static inline FXfloat log(FXfloat x){ return ::logf(x); }
551 
553 static inline FXdouble log(FXdouble x){ return ::log(x); }
554 
555 
557 #if defined(NO_LOG1PF)
558 static inline FXfloat log1p(FXfloat x){ return Math::log(1.0f+x); }
559 #else
560 static inline FXfloat log1p(FXfloat x){ return ::log1pf(x); }
561 #endif
562 
564 #if defined(NO_LOG1P)
565 static inline FXdouble log1p(FXdouble x){ return Math::log(1.0+x); }
566 #else
567 static inline FXdouble log1p(FXdouble x){ return ::log1p(x); }
568 #endif
569 
570 
572 #if defined(NO_LOG2F)
573 static inline FXfloat log2(FXfloat x){ return Math::log(x)*1.442695040888963407359924681001892137f; }
574 #else
575 static inline FXfloat log2(FXfloat x){ return ::log2f(x); }
576 #endif
577 
579 #if defined(NO_LOG2)
580 static inline FXdouble log2(FXdouble x){ return Math::log(x)*1.442695040888963407359924681001892137; }
581 #else
582 static inline FXdouble log2(FXdouble x){ return ::log2(x); }
583 #endif
584 
585 
587 static inline FXfloat log10(FXfloat x){ return ::log10f(x); }
588 
590 static inline FXdouble log10(FXdouble x){ return ::log10(x); }
591 
592 
594 static inline FXfloat sqrt(FXfloat x){ return ::sqrtf(x); }
595 
597 static inline FXdouble sqrt(FXdouble x){ return ::sqrt(x); }
598 
599 
601 #if defined(NO_CBRTF)
602 static inline FXfloat cbrt(FXfloat x){ return Math::pow(x,0.333333333333333333333333333333f); }
603 #else
604 static inline FXfloat cbrt(FXfloat x){ return ::cbrtf(x); }
605 #endif
606 
608 #if defined(NO_CBRT)
609 static inline FXdouble cbrt(FXdouble x){ return Math::pow(x,0.333333333333333333333333333333); }
610 #else
611 static inline FXdouble cbrt(FXdouble x){ return ::cbrt(x); }
612 #endif
613 
614 
616 static inline FXfloat sqr(FXfloat x){ return x*x; }
617 
619 static inline FXdouble sqr(FXdouble x){ return x*x; }
620 
621 
623 static inline FXfloat cub(FXfloat x){ return x*x*x; }
624 
626 static inline FXdouble cub(FXdouble x){ return x*x*x; }
627 
628 
630 #if defined(NO_FMAXF)
631 static inline FXfloat fmax(FXfloat x,FXfloat y){ return (x>y)?x:y; }
632 #else
633 static inline FXfloat fmax(FXfloat x,FXfloat y){ return ::fmaxf(x,y); }
634 #endif
635 
637 #if defined(NO_FMAX)
638 static inline FXdouble fmax(FXdouble x,FXdouble y){ return (x>y)?x:y; }
639 #else
640 static inline FXdouble fmax(FXdouble x,FXdouble y){ return ::fmax(x,y); }
641 #endif
642 
643 
645 #if defined(NO_FMINF)
646 static inline FXfloat fmin(FXfloat x,FXfloat y){ return (x<y)?x:y; }
647 #else
648 static inline FXfloat fmin(FXfloat x,FXfloat y){ return ::fminf(x,y); }
649 #endif
650 
652 #if defined(NO_FMINF)
653 static inline FXdouble fmin(FXdouble x,FXdouble y){ return (x<y)?x:y; }
654 #else
655 static inline FXdouble fmin(FXdouble x,FXdouble y){ return ::fmin(x,y); }
656 #endif
657 
658 
660 static inline FXfloat fclamp(FXfloat lo,FXfloat x,FXfloat hi){ return fmin(fmax(x,lo),hi); }
661 
663 static inline FXdouble fclamp(FXdouble lo,FXdouble x,FXdouble hi){ return fmin(fmax(x,lo),hi); }
664 
665 
667 #if defined(NO_COPYSIGNF)
668 static inline FXfloat copysign(FXfloat x,FXfloat y){
669  union{ FXfloat f; FXuint u; } xx={x},yy={y}; xx.u&=0x7fffffff; xx.u|=(yy.u&0x80000000); return xx.f;
670  }
671 #else
672 static inline FXfloat copysign(FXfloat x,FXfloat y){ return ::copysignf(x,y); }
673 #endif
674 
675 
677 #if defined(NO_COPYSIGN)
678 static inline FXdouble copysign(FXdouble x,FXdouble y){
679  union{ FXdouble f; FXulong u; } xx={x},yy={y}; xx.u&=FXULONG(0x7fffffffffffffff); xx.u|=(yy.u&FXULONG(0x8000000000000000)); return xx.f;
680  }
681 #else
682 static inline FXdouble copysign(FXdouble x,FXdouble y){ return ::copysign(x,y); }
683 #endif
684 
685 
687 extern FXAPI FXfloat ipow(FXfloat base,FXint ex);
688 
690 extern FXAPI FXdouble ipow(FXdouble base,FXint ex);
691 
692 }
693 
694 }
695 
696 #endif

Copyright © 1997-2016 Jeroen van der Zijp