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,2018 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 #define NO_FDIMF
146 #define NO_FDIM
147 #endif
148 
149 // Systems below are missing these functions
150 #if defined(__sun__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__DragonFly__)
151 #define NO_EXP10F
152 #define NO_EXP10
153 #endif
154 
155 namespace FX {
156 
157 /********************************* Constants *********************************/
158 
160 const FXdouble PI=3.1415926535897932384626433833;
161 
163 const FXdouble EULER=2.7182818284590452353602874713;
164 
166 const FXdouble DTOR=0.0174532925199432957692369077;
167 
169 const FXdouble RTOD=57.295779513082320876798154814;
170 
171 /********************************* Functions *********************************/
172 
173 // FOX math functions live here
174 namespace Math {
175 
176 
178 static inline FXuint fpSign(FXfloat x){
179  union{ FXfloat f; FXuint u; } z={x}; return (z.u>>31);
180  }
181 
183 static inline FXulong fpSign(FXdouble x){
184  union{ FXdouble f; FXulong u; } z={x}; return (z.u>>63);
185  }
186 
187 
189 static inline FXuint fpMantissa(FXfloat x){
190  union{ FXfloat f; FXuint u; } z={x}; return (z.u&0x007fffff);
191  }
192 
194 static inline FXulong fpMantissa(FXdouble x){
195  union{ FXdouble f; FXulong u; } z={x}; return (z.u&FXULONG(0x000fffffffffffff));
196  }
197 
198 
200 static inline FXuint fpExponent(FXfloat x){
201  union{ FXfloat f; FXuint u; } z={x}; return ((z.u>>23)&0xff);
202  }
203 
205 static inline FXulong fpExponent(FXdouble x){
206  union{ FXdouble f; FXulong u; } z={x}; return ((z.u>>52)&0x7ff);
207  }
208 
209 
211 static inline FXbool fpFinite(FXfloat x){
212  union{ FXfloat f; FXuint u; } z={x}; return ((z.u&0x7fffffff)<0x7f800000);
213  }
214 
216 static inline FXbool fpFinite(FXdouble x){
217  union{ FXdouble f; FXulong u; } z={x}; return ((z.u&FXULONG(0x7fffffffffffffff))<FXULONG(0x7ff0000000000000));
218  }
219 
220 
222 static inline FXbool fpInfinite(FXfloat x){
223  union{ FXfloat f; FXuint u; } z={x}; return ((z.u&0x7fffffff)==0x7f800000);
224  }
225 
227 static inline FXbool fpInfinite(FXdouble x){
228  union{ FXdouble f; FXulong u; } z={x}; return ((z.u&FXULONG(0x7fffffffffffffff))==FXULONG(0x7ff0000000000000));
229  }
230 
231 
233 static inline FXbool fpNan(FXfloat x){
234  union{ FXfloat f; FXuint u; } z={x}; return (0x7f800000<(z.u&0x7fffffff));
235  }
236 
238 static inline FXbool fpNan(FXdouble x){
239  union{ FXdouble f; FXulong u; } z={x}; return (FXULONG(0x7ff0000000000000)<(z.u&FXULONG(0x7fffffffffffffff)));
240  }
241 
242 
244 static inline FXbool fpNormal(FXfloat x){
245  union{ FXfloat f; FXuint u; } z={x};
246  return ((z.u&0x7fffffff)==0) || ((0x00800000<=(z.u&0x7fffffff)) && ((z.u&0x7fffffff)<0x7f800000));
247  }
248 
250 static inline FXbool fpNormal(FXdouble x){
251  union{ FXdouble f; FXulong u; } z={x};
252  return ((z.u&FXULONG(0x7fffffffffffffff))==0) || ((FXULONG(0x0010000000000000)<=(z.u&FXULONG(0x7fffffffffffffff))) && ((z.u&FXULONG(0x7fffffffffffffff))<FXULONG(0x7ff0000000000000)));
253  }
254 
255 
257 #if defined(NO_FABSF)
258 static inline FXfloat fabs(FXfloat x){ return (x<0.0f) ? -x : x; }
259 #else
260 static inline FXfloat fabs(FXfloat x){ return ::fabsf(x); }
261 #endif
262 
264 static inline FXdouble fabs(FXdouble x){ return ::fabs(x); }
265 
266 
268 static inline FXfloat fmod(FXfloat x,FXfloat y){ return ::fmodf(x,y); }
269 
271 static inline FXdouble fmod(FXdouble x,FXdouble y){ return ::fmod(x,y); }
272 
273 
274 
276 #if defined(NO_CEILF)
277 extern FXAPI FXfloat ceil(FXfloat x);
278 #else
279 static inline FXfloat ceil(FXfloat x){ return ::ceilf(x); }
280 #endif
281 
283 static inline FXdouble ceil(FXdouble x){ return ::ceil(x); }
284 
285 
287 #if defined(NO_FLOORF)
288 extern FXAPI FXfloat floor(FXfloat x);
289 #else
290 static inline FXfloat floor(FXfloat x){ return ::floorf(x); }
291 #endif
292 
294 static inline FXdouble floor(FXdouble x){ return ::floor(x); }
295 
297 #if defined(NO_ROUNDF)
298 extern FXAPI FXfloat round(FXfloat x);
299 #else
300 static inline FXfloat round(FXfloat x){ return ::roundf(x); }
301 #endif
302 
304 #if defined(NO_ROUND)
305 extern FXAPI FXdouble round(FXdouble x);
306 #else
307 static inline FXdouble round(FXdouble x){ return ::round(x); }
308 #endif
309 
310 
312 #if defined(NO_TRUNCF)
313 extern FXAPI FXfloat trunc(FXfloat x);
314 #else
315 static inline FXfloat trunc(FXfloat x){ return ::truncf(x); }
316 #endif
317 
319 #if defined(NO_TRUNC)
320 extern FXAPI FXdouble trunc(FXdouble x);
321 #else
322 static inline FXdouble trunc(FXdouble x){ return ::trunc(x); }
323 #endif
324 
326 #if defined(NO_NEARBYINTF)
327 extern FXAPI FXfloat nearbyint(FXfloat x);
328 #else
329 static inline FXfloat nearbyint(FXfloat x){ return ::nearbyintf(x); }
330 #endif
331 
333 #if defined(NO_NEARBYINT)
334 extern FXAPI FXdouble nearbyint(FXdouble x);
335 #else
336 static inline FXdouble nearbyint(FXdouble x){ return ::nearbyint(x); }
337 #endif
338 
340 #if defined(NO_RINTF)
341 extern FXAPI FXfloat rint(FXfloat x);
342 #else
343 static inline FXfloat rint(FXfloat x){ return ::rintf(x); }
344 #endif
345 
347 #if defined(NO_RINT)
348 extern FXAPI FXdouble rint(FXdouble x);
349 #else
350 static inline FXdouble rint(FXdouble x){ return ::rint(x); }
351 #endif
352 
354 static inline FXfloat sin(FXfloat x){ return ::sinf(x); }
355 
357 static inline FXdouble sin(FXdouble x){ return ::sin(x); }
358 
359 
361 static inline FXfloat cos(FXfloat x){ return ::cosf(x); }
362 
364 static inline FXdouble cos(FXdouble x){ return ::cos(x); }
365 
366 
368 static inline FXfloat tan(FXfloat x){ return ::tanf(x); }
369 
371 static inline FXdouble tan(FXdouble x){ return ::tan(x); }
372 
373 
375 static inline FXfloat asin(FXfloat x){ return ::asinf(x); }
376 
378 static inline FXdouble asin(FXdouble x){ return ::asin(x); }
379 
380 
382 static inline FXfloat acos(FXfloat x){ return ::acosf(x); }
383 
385 static inline FXdouble acos(FXdouble x){ return ::acos(x); }
386 
387 
389 static inline FXfloat atan(FXfloat x){ return ::atanf(x); }
390 
392 static inline FXdouble atan(FXdouble x){ return ::atan(x); }
393 
394 
396 static inline FXfloat atan2(FXfloat y,FXfloat x){ return ::atan2f(y,x); }
397 
399 static inline FXdouble atan2(FXdouble y,FXdouble x){ return ::atan2(y,x); }
400 
401 
403 #if defined(NO_SINHF)
404 extern FXAPI FXfloat sinh(FXfloat x);
405 #else
406 static inline FXfloat sinh(FXfloat x){ return ::sinhf(x); }
407 #endif
408 
410 #if defined(NO_SINH)
411 extern FXAPI FXdouble sinh(FXdouble x);
412 #else
413 static inline FXdouble sinh(FXdouble x){ return ::sinh(x); }
414 #endif
415 
416 
418 #if defined(NO_COSHF)
419 extern FXAPI FXfloat cosh(FXfloat x);
420 #else
421 static inline FXfloat cosh(FXfloat x){ return ::coshf(x); }
422 #endif
423 
425 #if defined(NO_COSH)
426 extern FXAPI FXdouble cosh(FXdouble x);
427 #else
428 static inline FXdouble cosh(FXdouble x){ return ::cosh(x); }
429 #endif
430 
431 
433 #if defined(NO_TANHF)
434 extern FXAPI FXfloat tanh(FXfloat x);
435 #else
436 static inline FXfloat tanh(FXfloat x){ return ::tanhf(x); }
437 #endif
438 
440 #if defined(NO_TANH)
441 extern FXAPI FXdouble tanh(FXdouble x);
442 #else
443 static inline FXdouble tanh(FXdouble x){ return ::tanh(x); }
444 #endif
445 
446 
448 #if defined(NO_ASINHF)
449 extern FXAPI FXfloat asinh(FXfloat x);
450 #else
451 static inline FXfloat asinh(FXfloat x){ return ::asinhf(x); }
452 #endif
453 
455 #if defined(NO_ASINH)
456 extern FXAPI FXdouble asinh(FXdouble x);
457 #else
458 static inline FXdouble asinh(FXdouble x){ return ::asinh(x); }
459 #endif
460 
461 
463 #if defined(NO_ACOSHF)
464 extern FXAPI FXfloat acosh(FXfloat x);
465 #else
466 static inline FXfloat acosh(FXfloat x){ return ::acoshf(x); }
467 #endif
468 
470 #if defined(NO_ACOSH)
471 extern FXAPI FXdouble acosh(FXdouble x);
472 #else
473 static inline FXdouble acosh(FXdouble x){ return ::acosh(x); }
474 #endif
475 
476 
478 #if defined(NO_ATANHF)
479 extern FXAPI FXfloat atanh(FXfloat x);
480 #else
481 static inline FXfloat atanh(FXfloat x){ return ::atanhf(x); }
482 #endif
483 
485 #if defined(NO_ATANH)
486 extern FXAPI FXdouble atanh(FXdouble x);
487 #else
488 static inline FXdouble atanh(FXdouble x){ return ::atanh(x); }
489 #endif
490 
491 
493 static inline FXfloat pow(FXfloat x,FXfloat y){ return ::powf(x,y); }
494 
496 static inline FXdouble pow(FXdouble x,FXdouble y){ return ::pow(x,y); }
497 
498 
500 static inline FXfloat exp(FXfloat x){ return ::expf(x); }
501 
503 static inline FXdouble exp(FXdouble x){ return ::exp(x); }
504 
505 
507 #if defined(NO_EXPM1F)
508 static inline FXfloat expm1(FXfloat x){ return ::expf(x)-1.0f; }
509 #else
510 static inline FXfloat expm1(FXfloat x){ return ::expm1f(x); }
511 #endif
512 
514 #if defined(NO_EXPM1)
515 static inline FXdouble expm1(FXdouble x){ return ::exp(x)-1.0; }
516 #else
517 static inline FXdouble expm1(FXdouble x){ return ::expm1(x); }
518 #endif
519 
520 
522 #if defined(NO_EXP2F)
523 static inline FXfloat exp2(FXfloat x){ return Math::pow(2.0f,x); }
524 #else
525 static inline FXfloat exp2(FXfloat x){ return ::exp2f(x); }
526 #endif
527 
529 #if defined(NO_EXP2)
530 static inline FXdouble exp2(FXdouble x){ return Math::pow(2.0,x); }
531 #else
532 static inline FXdouble exp2(FXdouble x){ return ::exp2(x); }
533 #endif
534 
535 
537 #if defined(NO_EXP10F)
538 static inline FXfloat exp10(FXfloat x){ return Math::pow(10.0f,x); }
539 #else
540 static inline FXfloat exp10(FXfloat x){ return ::exp10f(x); }
541 #endif
542 
544 #if defined(NO_EXP10)
545 static inline FXdouble exp10(FXdouble x){ return Math::pow(10.0,x); }
546 #else
547 static inline FXdouble exp10(FXdouble x){ return ::exp10(x); }
548 #endif
549 
550 
552 static inline FXfloat log(FXfloat x){ return ::logf(x); }
553 
555 static inline FXdouble log(FXdouble x){ return ::log(x); }
556 
557 
559 #if defined(NO_LOG1PF)
560 static inline FXfloat log1p(FXfloat x){ return Math::log(1.0f+x); }
561 #else
562 static inline FXfloat log1p(FXfloat x){ return ::log1pf(x); }
563 #endif
564 
566 #if defined(NO_LOG1P)
567 static inline FXdouble log1p(FXdouble x){ return Math::log(1.0+x); }
568 #else
569 static inline FXdouble log1p(FXdouble x){ return ::log1p(x); }
570 #endif
571 
572 
574 #if defined(NO_LOG2F)
575 static inline FXfloat log2(FXfloat x){ return Math::log(x)*1.442695040888963407359924681001892137f; }
576 #else
577 static inline FXfloat log2(FXfloat x){ return ::log2f(x); }
578 #endif
579 
581 #if defined(NO_LOG2)
582 static inline FXdouble log2(FXdouble x){ return Math::log(x)*1.442695040888963407359924681001892137; }
583 #else
584 static inline FXdouble log2(FXdouble x){ return ::log2(x); }
585 #endif
586 
587 
589 static inline FXfloat log10(FXfloat x){ return ::log10f(x); }
590 
592 static inline FXdouble log10(FXdouble x){ return ::log10(x); }
593 
594 
596 static inline FXfloat sqrt(FXfloat x){ return ::sqrtf(x); }
597 
599 static inline FXdouble sqrt(FXdouble x){ return ::sqrt(x); }
600 
601 
603 #if defined(NO_CBRTF)
604 static inline FXfloat cbrt(FXfloat x){ return Math::pow(x,0.333333333333333333333333333333f); }
605 #else
606 static inline FXfloat cbrt(FXfloat x){ return ::cbrtf(x); }
607 #endif
608 
610 #if defined(NO_CBRT)
611 static inline FXdouble cbrt(FXdouble x){ return Math::pow(x,0.333333333333333333333333333333); }
612 #else
613 static inline FXdouble cbrt(FXdouble x){ return ::cbrt(x); }
614 #endif
615 
616 
618 static inline FXfloat sqr(FXfloat x){ return x*x; }
619 
621 static inline FXdouble sqr(FXdouble x){ return x*x; }
622 
623 
625 static inline FXfloat cub(FXfloat x){ return x*x*x; }
626 
628 static inline FXdouble cub(FXdouble x){ return x*x*x; }
629 
630 
632 #if defined(NO_FMAXF)
633 static inline FXfloat fmax(FXfloat x,FXfloat y){ return (x>y)?x:y; }
634 #else
635 static inline FXfloat fmax(FXfloat x,FXfloat y){ return ::fmaxf(x,y); }
636 #endif
637 
639 #if defined(NO_FMAX)
640 static inline FXdouble fmax(FXdouble x,FXdouble y){ return (x>y)?x:y; }
641 #else
642 static inline FXdouble fmax(FXdouble x,FXdouble y){ return ::fmax(x,y); }
643 #endif
644 
645 
647 #if defined(NO_FMINF)
648 static inline FXfloat fmin(FXfloat x,FXfloat y){ return (x<y)?x:y; }
649 #else
650 static inline FXfloat fmin(FXfloat x,FXfloat y){ return ::fminf(x,y); }
651 #endif
652 
654 #if defined(NO_FMIN)
655 static inline FXdouble fmin(FXdouble x,FXdouble y){ return (x<y)?x:y; }
656 #else
657 static inline FXdouble fmin(FXdouble x,FXdouble y){ return ::fmin(x,y); }
658 #endif
659 
661 #if defined(NO_FDIMF)
662 static inline FXfloat fdim(FXfloat x,FXfloat y){ return fmax(x-y,0.0f); }
663 #else
664 static inline FXfloat fdim(FXfloat x,FXfloat y){ return ::fdimf(x,y); }
665 #endif
666 
667 
669 #if defined(NO_FDIM)
670 static inline FXdouble fdim(FXdouble x,FXdouble y){ return fmax(x-y,0.0); }
671 #else
672 static inline FXdouble fdim(FXdouble x,FXdouble y){ return ::fdim(x,y); }
673 #endif
674 
675 
677 static inline FXfloat fclamp(FXfloat lo,FXfloat x,FXfloat hi){ return fmin(fmax(x,lo),hi); }
678 
680 static inline FXdouble fclamp(FXdouble lo,FXdouble x,FXdouble hi){ return fmin(fmax(x,lo),hi); }
681 
682 
684 inline FXint imin(FXint x,FXint y){ return (x<y)?x:y; }
685 inline FXlong imin(FXlong x,FXlong y){ return (x<y)?x:y; }
686 
687 
689 inline FXint imax(FXint x,FXint y){ return (x>y)?x:y; }
690 inline FXlong imax(FXlong x,FXlong y){ return (x>y)?x:y; }
691 
692 
694 inline FXint iabs(FXint x){ return 0<x?x:-x; }
695 inline FXlong iabs(FXlong x){ return 0L<x?x:-x; }
696 
697 
699 inline FXint iclamp(FXint lo,FXint x,FXint hi){ return imin(imax(x,lo),hi); }
700 inline FXlong iclamp(FXlong lo,FXlong x,FXlong hi){ return imin(imax(x,lo),hi); }
701 
702 
704 #if defined(NO_COPYSIGNF)
705 static inline FXfloat copysign(FXfloat x,FXfloat y){
706  union{ FXfloat f; FXuint u; } xx={x},yy={y}; xx.u&=0x7fffffff; xx.u|=(yy.u&0x80000000); return xx.f;
707  }
708 #else
709 static inline FXfloat copysign(FXfloat x,FXfloat y){
710  return ::copysignf(x,y);
711  }
712 #endif
713 
714 
716 #if defined(NO_COPYSIGN)
717 static inline FXdouble copysign(FXdouble x,FXdouble y){
718  union{ FXdouble f; FXulong u; } xx={x},yy={y}; xx.u&=FXULONG(0x7fffffffffffffff); xx.u|=(yy.u&FXULONG(0x8000000000000000)); return xx.f;
719  }
720 #else
721 static inline FXdouble copysign(FXdouble x,FXdouble y){
722  return ::copysign(x,y);
723  }
724 #endif
725 
726 
728 extern FXAPI FXfloat ipow(FXfloat base,FXint ex);
729 
731 extern FXAPI FXdouble ipow(FXdouble base,FXint ex);
732 
733 }
734 
735 }
736 
737 #endif
Definition: FX4Splitter.h:28

Copyright © 1997-2018 Jeroen van der Zijp