00001
00033 #ifndef _MATH_H_
00034 #define _MATH_H_
00035
00036 #include <nlibc.h>
00037
00038 #define _INLINE_MATH_
00040 #ifdef _INLINE_MATH_
00041 # define math_inline inline
00042 #else
00043 # define math_inline
00044 #endif
00045
00052 #define _math_setdouble(U,D) { \
00053 register union { double d; unsigned i; } u; \
00054 asm("\tatr0h %0 <"#U">" : "=r" (u.i)); D=u.d; \
00055 }
00056
00057
00058
00059
00060
00061
00062
00063 #include <stdint.h>
00064 #include <limits.h>
00065 #include <float.h>
00066
00067
00068
00069
00073 #define INFINITY 0x1.0p32767
00074
00078 #define HUGE_VAL INFINITY
00079
00080
00085 #define HUGE_VALF HUGE_VAL
00086 #define HUGE_VALL HUGE_VAL
00087
00088
00091 #undef NAN
00092
00097 #define FP_INFINITE 2
00098 #define FP_NAN 3
00099 #define FP_NORMAL 1
00100 #define FP_SUBNORMAL 1
00101 #define FP_ZERO 4
00102
00107 #define FP_FAST_FMA
00108
00110 #define FP_FAST_FMAF FP_FAST_FMA
00111 #define FP_FAST_FMAL FP_FAST_FMA
00112
00116 #define FP_ILOGB0 -INT_MAX
00117 #define FP_ILOGBNAN INT_MAX
00118
00120 #define MATH_ERRNO 1
00121 #define MATH_ERREXCEPT 2
00122 #define math_errhandling
00123
00124 #include "math_suppl.h"
00125
00126
00146
00147 #pragma STDC FP_CONTRACT
00148
00187
00188 #define fpclassify(x) _fpclassify(x)
00189
00190
00218
00219 #define isfinite(x) _isfinite(x)
00220
00244
00245
00246
00247 #define isinf(x) _isinf(x)
00248
00272
00273 #define isnan(x) _isnan(x)
00274
00297
00298 #define isnormal(x) _isfinite(x)
00299
00324
00325 #define signbit(x) _signbit(x)
00326
00351
00352 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00353 extern math_inline double sqrt( double a );
00354 #else
00355 #if defined(_uses_sqrt_math_h) || !defined(__cflow_processed)
00356 math_inline double sqrt( double a )
00357 {
00358 register double ris, tmp_a2;
00359 register double three_half, one_half;
00360 register double aR;
00361
00362 _math_setdouble(0x3FE0000000000000,one_half);
00363 _math_setdouble(0x3FF8000000000000,three_half);
00364
00365 aR = a;
00366 ris = 0.0;
00367
00368 where ( aR ) {
00369 asm("\tlutmove %0 $ZERO" : "=r" (ris));
00370 asm("\tlutisqrt.L %0 %1" : "=r" (ris) : "r" (aR));
00371 }
00372 tmp_a2 = aR * one_half;
00373 ris = ris*( three_half - tmp_a2 * ris * ris);
00374 ris = ris*( three_half - tmp_a2 * ris * ris);
00375 ris = ris*( three_half - tmp_a2 * ris * ris);
00376 ris = ris*( three_half - tmp_a2 * ris * ris);
00377 ris *= aR;
00378 return ris;
00379 }
00380 #endif
00381 #endif // Has Main
00382
00430
00431 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00432 extern math_inline double log(double x);
00433 #else
00434 #if defined(_uses_log_math_h) || !defined(__cflow_processed)
00435 math_inline double log(double x)
00436 {
00437 register double xx, x0, e, e1, r, r2, r4;
00438 register double P, Pa, Pb, Pc, Pd;
00439 register double trail;
00440 register double log2e, ln2lead, ln2trail, nummag;
00441
00442 register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
00443 register double p10, p11, p12, p13, p14, p15, p16, p17, p18, p19;
00444 register double p20, p21, p22, p23, p24, p25, p26, p27, p28, p29;
00445 register double p30, p31, p32, p33, p34, p35, p36;
00446
00447 asm("\n\t!!-- begin log()");
00448 _math_setdouble( 0x3ff71547652b82fe, log2e );
00449 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00450 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00451 _math_setdouble( 0x43300000000003ff, nummag );
00452
00453
00454 _math_setdouble( 0xbfe0000000000000 , p0 );
00455 _math_setdouble( 0x3fd5555555555555 , p1 );
00456 _math_setdouble( 0xbfcfffffffffffd2 , p2 );
00457 _math_setdouble( 0x3fc9999999999944 , p3 );
00458 _math_setdouble( 0xbfc555555555839f , p4 );
00459 _math_setdouble( 0x3fc24924924994cb , p5 );
00460 _math_setdouble( 0xbfbfffffffd3792a , p6 );
00461 _math_setdouble( 0x3fbc71c71bfbb905 , p7 );
00462 _math_setdouble( 0xbfb99999a6067f7a , p8 );
00463 _math_setdouble( 0x3fb745d1960bf8dd , p9 );
00464 _math_setdouble( 0xbfb555531a405781 , p10 );
00465 _math_setdouble( 0x3fb3b1351bb667d8 , p11 );
00466 _math_setdouble( 0xbfb2496af8fbbbe4 , p12 );
00467 _math_setdouble( 0x3fb111c6afc8c6e1 , p13 );
00468 _math_setdouble( 0xbfaff38dd41057ce , p14 );
00469 _math_setdouble( 0x3fadffb7d7a94696 , p15 );
00470 _math_setdouble( 0xbfad41ba8a134738 , p16 );
00471 _math_setdouble( 0x3faccbc9726ece12 , p17 );
00472 _math_setdouble( 0xbf9ec38f119d3d06 , p18 );
00473 _math_setdouble( 0x3f785f81962a50fb , p19 );
00474 _math_setdouble( 0xbfce4be7a8a5d72b , p20 );
00475 _math_setdouble( 0x3fd9d8d252726e6c , p21 );
00476 _math_setdouble( 0x3ff5c8aa212fd722 , p22 );
00477 _math_setdouble( 0xc0026bd5ff44cd4e , p23 );
00478 _math_setdouble( 0xc01fa5187761a8ad , p24 );
00479 _math_setdouble( 0x4026d78e0bf83a6c , p25 );
00480 _math_setdouble( 0x4040ba1a1b262a4f , p26 );
00481 _math_setdouble( 0xc044570c25ae2da0 , p27 );
00482 _math_setdouble( 0xc05a8787b4194713 , p28 );
00483 _math_setdouble( 0x405a009c5d877e88 , p29 );
00484 _math_setdouble( 0x406e49c81a0007b0 , p30 );
00485 _math_setdouble( 0xc0666aa1bfe5d0fe , p31 );
00486 _math_setdouble( 0xc077926b8e4542e3 , p32 );
00487 _math_setdouble( 0x406767610205d729 , p33 );
00488 _math_setdouble( 0x40765b8a9462a4c6 , p34 );
00489 _math_setdouble( 0xc0564d5567c48d46 , p35 );
00490 _math_setdouble( 0xc06383c8abcc91fa , p36 );
00491
00492 xx = x;
00493
00494 asm("\tlutmove %0 $ZERO\n\tlutlogm.L %0 %1" : "=r" (x0) : "r" (xx));
00495 asm("\tlutmove %0 $ZERO\n\tlutloge.L %0 %1" : "=r" (e1) : "r" (xx));
00496
00497 e = e1 - nummag;
00498 r = x0 - 1.0;
00499 r2 = r * r;
00500 r4 = r2 * r2;
00501
00502 Pa = p36;
00503 Pa = r4 * Pa + p32;
00504 Pa = r4 * Pa + p28;
00505 Pa = r4 * Pa + p24;
00506 Pa = r4 * Pa + p20;
00507 Pa = r4 * Pa + p16;
00508 Pa = r4 * Pa + p12;
00509 Pa = r4 * Pa + p8;
00510 Pa = r4 * Pa + p4;
00511 Pa = r4 * Pa + p0;
00512
00513 Pb = p33;
00514 Pb = r4 * Pb + p29;
00515 Pb = r4 * Pb + p25;
00516 Pb = r4 * Pb + p21;
00517 Pb = r4 * Pb + p17;
00518 Pb = r4 * Pb + p13;
00519 Pb = r4 * Pb + p9;
00520 Pb = r4 * Pb + p5;
00521 Pb = r4 * Pb + p1;
00522
00523 Pc = p34;
00524 Pc = r4 * Pc + p30;
00525 Pc = r4 * Pc + p26;
00526 Pc = r4 * Pc + p22;
00527 Pc = r4 * Pc + p18;
00528 Pc = r4 * Pc + p14;
00529 Pc = r4 * Pc + p10;
00530 Pc = r4 * Pc + p6;
00531 Pc = r4 * Pc + p2;
00532
00533 Pd = p35;
00534 Pd = r4 * Pd + p31;
00535 Pd = r4 * Pd + p27;
00536 Pd = r4 * Pd + p23;
00537 Pd = r4 * Pd + p19;
00538 Pd = r4 * Pd + p15;
00539 Pd = r4 * Pd + p11;
00540 Pd = r4 * Pd + p7;
00541 Pd = r4 * Pd + p3;
00542
00543 P = Pa + r * Pb + r2 * (Pc + r * Pd);
00544
00545 trail = e * ln2trail;
00546 trail = r2 * P + trail;
00547 trail = trail + r;
00548 P = trail + e * ln2lead;
00549
00550 asm("\n\t!!-- end log()");
00551 return P;
00552 }
00553 #endif
00554 #endif // Has Main
00555
00603
00604 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00605 extern math_inline double exp(double x);
00606 #else
00607 #if defined(_uses_exp_math_h) || !defined(__cflow_processed)
00608 math_inline double exp(double x)
00609 {
00610 register double PP,QQ,Qh,res;
00611 register double b,z,f;
00612 register double q,qlead,qtrail;
00613 register double q2,q4,q5;
00614 register double t1,t2,t3;
00615 register double t1h,t2h,t3h;
00616 register double log2e,ln2lead,ln2trail,nummag;
00617 register double p0,p1,p2,p3,p4,p5,p6,p7,p8;
00618 register double half;
00619
00620 _math_setdouble( 0x3fe0000000000000 , half );
00621
00622 _math_setdouble( 0x3ff71547652b82fe, log2e );
00623 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00624 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00625 _math_setdouble( 0x43300000000003ff, nummag );
00626
00627
00628 _math_setdouble( 0x3fc5555555555502 , p0 );
00629 _math_setdouble( 0x3fa555555555320b , p1 );
00630 _math_setdouble( 0x3f81111111128589 , p2 );
00631 _math_setdouble( 0x3f56c16c17cc1b0b , p3 );
00632 _math_setdouble( 0x3f2a01a011cdf3cb , p4 );
00633 _math_setdouble( 0x3efa019ab32afe96 , p5 );
00634 _math_setdouble( 0x3ec71df5419f16f5 , p6 );
00635 _math_setdouble( 0x3e9289f84ba3248e , p7 );
00636 _math_setdouble( 0x3e5ad2147cc869b8 , p8 );
00637
00638 b = log2e * x;
00639 z = nummag + b;
00640 f = z - nummag;
00641
00642 asm("\tlutmove %0 $ZERO" : "=r" (PP));
00643 asm("\tlutexp.L %0 %1" : "=r" (PP) : "r" (z));
00644
00645 qlead = x - f * ln2lead;
00646 qtrail = - f * ln2trail;
00647 q = qlead + qtrail;
00648 q2 = q * q;
00649 q4 = q2 * q2;
00650 q5 = q * q4;
00651
00652 t1h = p7 + q * p8;
00653 t2h = p4 + q * p5;
00654 t3h = p6 + q * t1h;
00655 Qh = t2h + q2 * t3h;
00656
00657 t1 = p2 + q * p3;
00658 t2 = half + q * p0;
00659 t3 = p1 + q * t1;
00660 QQ = t2 + q2 * t3;
00661
00662 QQ = QQ + q5 * Qh;
00663 QQ = qtrail + q2 * QQ;
00664 QQ = qlead + QQ;
00665
00666 res = PP + PP * QQ;
00667
00668 return res;
00669 }
00670 #endif
00671 #endif // Has Main
00672
00698
00699 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00700 extern math_inline double expm1(double x);
00701 #else
00702 #if defined(_uses_expm1_math_h) || !defined(__cflow_processed)
00703 math_inline double expm1(double x)
00704 {
00705 register double PP, Pm1, QQ, Qh, res;
00706 register double b, z, f;
00707 register double q, qlead, qtrail;
00708 register double q2, q4, q5;
00709 register double t1, t2, t3;
00710 register double t1h, t2h, t3h;
00711 register double log2e, ln2lead, ln2trail, nummag;
00712 register double p0, p1, p2, p3, p4, p5, p6, p7, p8;
00713 register double half;
00714
00715 _math_setdouble( 0x3fe0000000000000 , half );
00716
00717 _math_setdouble( 0x3ff71547652b82fe, log2e );
00718 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
00719 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
00720 _math_setdouble( 0x43300000000003ff, nummag );
00721
00722
00723 _math_setdouble( 0x3fc5555555555502 , p0 );
00724 _math_setdouble( 0x3fa555555555320b , p1 );
00725 _math_setdouble( 0x3f81111111128589 , p2 );
00726 _math_setdouble( 0x3f56c16c17cc1b0b , p3 );
00727 _math_setdouble( 0x3f2a01a011cdf3cb , p4 );
00728 _math_setdouble( 0x3efa019ab32afe96 , p5 );
00729 _math_setdouble( 0x3ec71df5419f16f5 , p6 );
00730 _math_setdouble( 0x3e9289f84ba3248e , p7 );
00731 _math_setdouble( 0x3e5ad2147cc869b8 , p8 );
00732
00733 b = log2e * x;
00734 z = nummag + b;
00735 f = z - nummag;
00736
00737 asm("\tlutmove %0 $ZERO" : "=r" (PP));
00738 asm("\tlutexp.L %0 %1" : "=r" (PP) : "r" (z));
00739
00740 Pm1 = PP - 1.0;
00741
00742 qlead = x - f * ln2lead;
00743 qtrail = - f * ln2trail;
00744 q = qlead + qtrail;
00745 q2 = q * q;
00746 q4 = q2 * q2;
00747 q5 = q * q4;
00748
00749 t1h = p7 + q * p8;
00750 t2h = p4 + q * p5;
00751 t3h = p6 + q * t1h;
00752 Qh = t2h + q2 * t3h;
00753
00754 t1 = p2 + q * p3;
00755 t2 = half + q * p0;
00756 t3 = p1 + q * t1;
00757 QQ = t2 + q2 * t3;
00758
00759 QQ = QQ + q5 * Qh;
00760 QQ = qtrail + q2 * QQ;
00761 QQ = qlead + QQ;
00762
00763 res = Pm1 + PP * QQ;
00764
00765 return res;
00766 }
00767 #endif
00768 #endif // Has Main
00769
00802
00803 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00804 extern math_inline double acos(double x);
00805 #else
00806 #if defined(_uses_acos_math_h) || !defined(__cflow_processed)
00807 math_inline double acos(double x)
00808 {
00809 register double xx, y, absx, res;
00810 register double half, two;
00811 register double pihalflead, pihalftrail;
00812
00813 _math_setdouble( 0x3ff9220000000000 , pihalflead );
00814 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
00815
00816 half = 0.5;
00817 two = 1.0 + 1.0;
00818
00819 xx =x;
00820 absx = xx;
00821 where ( xx < 0.0 ) {
00822 absx = - absx;
00823 }
00824 y = absx;
00825 where ( absx > half ) {
00826 y = half - half * absx;
00827 y = sqrt(y);
00828 }
00829
00830 res = asin_k(y);
00831
00832 where ( xx < 0.0 ) {
00833 res = - res;
00834 }
00835
00836 where ( absx > half ) {
00837 res = two * res;
00838 }
00839 where ( absx <= half ) {
00840 res = pihalftrail - res;
00841 res = pihalflead + res;
00842 }
00843 where ( xx + half < 0.0) {
00844 res = two * pihalftrail + res;
00845 res = two * pihalflead + res;
00846 }
00847
00848 return res;
00849 }
00850 #endif
00851 #endif // Has Main
00852
00886
00887 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00888 extern math_inline double asin(double x);
00889 #else
00890 #if defined(_uses_asin_math_h) || !defined(__cflow_processed)
00891 math_inline double asin(double x)
00892 {
00893 register double xx, y, absx, res;
00894 register double half, two;
00895 register double pihalflead, pihalftrail;
00896
00897 _math_setdouble( 0x3ff9220000000000 , pihalflead );
00898 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
00899
00900 half = 0.5;
00901 two = 1.0 + 1.0;
00902
00903 xx = x;
00904 absx = xx;
00905 where ( xx < 0.0 ) {
00906 absx = - absx;
00907 }
00908 y = absx ;
00909 where ( absx > half ) {
00910 y = half - half * y;
00911 y = sqrt(y);
00912 }
00913
00914 res = asin_k(y);
00915
00916 where ( absx > half ) {
00917 res = pihalftrail - two * res;
00918 res = pihalflead + res;
00919 }
00920 where ( xx < 0.0 ) {
00921 res = - res;
00922 }
00923
00924 return res;
00925 }
00926 #endif
00927 #endif // Has Main
00928
00961
00962 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
00963 extern math_inline double atan(double x);
00964 #else
00965 #if defined(_uses_atan_math_h) || !defined(__cflow_processed)
00966 math_inline double atan(double x)
00967 {
00968 register double xx, absx, y, res;
00969 register double pihalflead, pihalftrail;
00970
00971 _math_setdouble( 0x3ff9220000000000 , pihalflead );
00972 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
00973
00974 xx = x;
00975 absx = xx;
00976 where ( xx < 0.0 ) {
00977 absx = - absx;
00978 }
00979
00980 y = absx;
00981 where ( absx > 1.0 ) {
00982 y = 1.0 / absx;
00983 }
00984
00985 res = atan_k( y );
00986
00987 where ( absx > 1.0 ) {
00988 res = pihalftrail - res;
00989 res = pihalflead + res;
00990 }
00991 where ( xx < 0.0 ) {
00992 res = - res;
00993 }
00994
00995 return res;
00996 }
00997 #endif
00998 #endif // Has Main
00999
01030
01031 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01032 extern math_inline double atan2(double y, double x);
01033 #else
01034 #if defined(_uses_atan2_math_h) || !defined(__cflow_processed)
01035 math_inline double atan2(double y, double x)
01036 {
01037 register double xx, absx, z, res, pi;
01038 register double pihalflead, pihalftrail;
01039
01040 _math_setdouble( 0x3ff9220000000000 , pihalflead );
01041 _math_setdouble( 0xbed2aeef4b9ee59e , pihalftrail );
01042 pi = 3.14159265358979323846;
01043
01044 where (x == 0.0) {
01045 res = 0.0;
01046
01047 where ( y > 0.0) {
01048 res = 0.5 * pi;
01049 }
01050 where ( y < 0.0) {
01051 res = -0.5 * pi;
01052 }
01053
01054 } else {
01055
01056 xx = y/x;
01057 absx = xx;
01058 where ( xx < 0.0 ) {
01059 absx = - absx;
01060 }
01061
01062 z = absx;
01063 where ( absx > 1.0 ) {
01064 z = 1.0 / absx;
01065 }
01066
01067 res = atan_k( z );
01068
01069 where ( absx > 1.0 ) {
01070 res = pihalftrail - res;
01071 res = pihalflead + res;
01072 }
01073
01074 where ( x < 0.0 ) {
01075 res = res - pi;
01076 }
01077 where (xx <= 0.0 ) {
01078 res = -res;
01079 }
01080
01081 }
01082
01083 return res;
01084 }
01085 #endif
01086 #endif // Has Main
01087
01113
01114 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01115 extern math_inline double cos(double x);
01116 #else
01117 #if defined(_uses_cos_math_h) || !defined(__cflow_processed)
01118 math_inline double cos(double x)
01119 {
01120 register double y, siny, cosy;
01121 register double res, f;
01122 register union {
01123 double z;
01124 int zint;
01125 } zu;
01126 register int k;
01127 register double twooverpi, pihalflead, pihalftrail1, pihalftrail2, magic2;
01128
01129 _math_setdouble( 0x3fe45f306dc9c883 , twooverpi );
01130 _math_setdouble( 0x4337ffffffffffff , magic2 );
01131 _math_setdouble( 0x3ff921fb50000000 , pihalflead );
01132 _math_setdouble( 0x3e5110b460000000 , pihalftrail1 );
01133 _math_setdouble( 0x3c91a62633145c07 , pihalftrail2 );
01134
01135 zu.z = magic2 + twooverpi * x;
01136 f = zu.z - magic2;
01137 y = x - f * pihalflead;
01138 y = y - f * pihalftrail1;
01139 y = y - f * pihalftrail2;
01140
01141
01142
01143 siny = sin_1oct(y);
01144 cosy = cos_1oct(y);
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155 k = 0x3;
01156 k = zu.zint & k ;
01157
01158 where ( k == 3 ) {
01159 res = cosy;
01160 }
01161 where ( k == 0 ) {
01162 res = - siny;
01163 }
01164 where ( k == 1 ) {
01165 res = - cosy;
01166 }
01167 where ( k == 2 ) {
01168 res = siny;
01169 }
01170
01171 return res;
01172 }
01173 #endif
01174 #endif // Has Main
01175
01202
01203 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01204 extern math_inline double sin(double x);
01205 #else
01206 #if defined(_uses_sin_math_h) || !defined(__cflow_processed)
01207 math_inline double sin(double x)
01208 {
01209 register double y, siny, cosy;
01210 register double res, f;
01211 register union {
01212 double z;
01213 int zint;
01214 } zu;
01215 register int k;
01216 register double twooverpi, pihalflead, pihalftrail1, pihalftrail2, magic2;
01217
01218 _math_setdouble( 0x3fe45f306dc9c883 , twooverpi );
01219 _math_setdouble( 0x4337ffffffffffff , magic2 );
01220 _math_setdouble( 0x3ff921fb50000000 , pihalflead );
01221 _math_setdouble( 0x3e5110b460000000 , pihalftrail1 );
01222 _math_setdouble( 0x3c91a62633145c07 , pihalftrail2 );
01223
01224 zu.z = magic2 + twooverpi * x;
01225 f = zu.z - magic2;
01226 y = x - f * pihalflead;
01227 y = y - f * pihalftrail1;
01228 y = y - f * pihalftrail2;
01229
01230
01231
01232
01233
01234 siny = sin_1oct(y);
01235 cosy = cos_1oct(y);
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246 k = 0x3;
01247 k = zu.zint & k;
01248
01249 where ( k == 3 ) {
01250 res = siny;
01251 }
01252 where ( k == 0 ) {
01253 res = cosy;
01254 }
01255 where ( k == 1 ) {
01256 res = - siny;
01257 }
01258 where ( k == 2 ) {
01259 res = - cosy;
01260 }
01261
01262 return res;
01263 }
01264 #endif
01265 #endif // Has Main
01266
01333
01334 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01335 extern math_inline double tan(double x);
01336 #else
01337 #if defined(_uses_tan_math_h) || !defined(__cflow_processed)
01338 math_inline double tan(double x)
01339 {
01340 register double y, y2, y3, y4, invy;
01341 register double res, Q, P, Qn, Qp, Pn, Pp;
01342
01343 register double p0, p1, p2, p3, p4, p5, p6, p7, p8, p9;
01344 register double p10, p11, p12, p13;
01345 register double q0, q1, q2, q3, q4, q5, q6, q7, q8, q9, q10;
01346
01347 register double f;
01348
01349 register union {
01350 double z;
01351 int zint;
01352 } zu;
01353
01354 register int k;
01355 register double twooverpi,pihalflead,pihalftrail1,pihalftrail2,magic2;
01356
01357 _math_setdouble( 0x3fe45f306dc9c883 , twooverpi );
01358 _math_setdouble( 0x4337ffffffffffff , magic2 );
01359 _math_setdouble( 0x3ff921fb50000000 , pihalflead );
01360 _math_setdouble( 0x3e5110b460000000 , pihalftrail1 );
01361 _math_setdouble( 0x3c91a62633145c07 , pihalftrail2 );
01362
01363
01364 _math_setdouble( 0x3fd55555555554f2 , p0 );
01365 _math_setdouble( 0x3fc111111111823f , p1 );
01366 _math_setdouble( 0x3faba1ba1b472c71 , p2 );
01367 _math_setdouble( 0x3f9664f49a7087a7 , p3 );
01368 _math_setdouble( 0x3f8226e1281741ed , p4 );
01369 _math_setdouble( 0x3f6d6d92e4dc1ec9 , p5 );
01370 _math_setdouble( 0x3f57d5b9d094e180 , p6 );
01371 _math_setdouble( 0x3f437f87931093e9 , p7 );
01372 _math_setdouble( 0x3f2d28899e55dabc , p8 );
01373 _math_setdouble( 0x3f21df93999dc111 , p9 );
01374 _math_setdouble( 0xbefb6ea2534187cb , p10 );
01375 _math_setdouble( 0x3f17656fc1431ef6 , p11 );
01376 _math_setdouble( 0xbf0778cb8106dd3d , p12 );
01377 _math_setdouble( 0x3ef5d99c5b37b8fb , p13 );
01378
01379 _math_setdouble( 0x3fd5555555555555 , q0 );
01380 _math_setdouble( 0x3f96c16c16c16c16 , q1 );
01381 _math_setdouble( 0x3f61566abc011734 , q2 );
01382 _math_setdouble( 0x3f2bbd7793321936 , q3 );
01383 _math_setdouble( 0x3ef66a8f2d1bc68f , q4 );
01384 _math_setdouble( 0x3ec228059183e28c , q5 );
01385 _math_setdouble( 0x3e8d6dc6da8b4b97 , q6 );
01386 _math_setdouble( 0x3e57d86d9f6cba62 , q7 );
01387 _math_setdouble( 0x3e23722fc10fb082 , q8 );
01388 _math_setdouble( 0x3ded3f62bcb56407 , q9 );
01389 _math_setdouble( 0x3dc2113add876256 , q10 );
01390
01391 zu.z = magic2 + twooverpi * x;
01392 f = zu.z - magic2;
01393 y = x - f * pihalflead;
01394 y = y - f * pihalftrail1;
01395 y = y - f * pihalftrail2;
01396
01397 y2 = y * y;
01398 y3 = y * y2;
01399 y4 = y2 * y2;
01400
01401 invy = y;
01402 where ( invy == 0.0) {
01403 invy = 1.0;
01404 }
01405 invy = 1.0 / invy;
01406
01407 Pp = p13;
01408 Pn = p12;
01409 Pp = y4*Pp + p11;
01410 Pn = y4*Pn + p10;
01411 Pp = y4*Pp + p9;
01412 Pn = y4*Pn + p8;
01413 Pp = y4*Pp + p7;
01414 Pn = y4*Pn + p6;
01415 Pp = y4*Pp + p5;
01416 Pn = y4*Pn + p4;
01417 Pp = y4*Pp + p3;
01418 Pn = y4*Pn + p2;
01419 Pp = y4*Pp + p1;
01420 Pn = y4*Pn + p0;
01421 P = y + y3 *(Pn+y2*Pp);
01422
01423 Qn = q10;
01424 Qp = q9;
01425 Qn = y4*Qn + q8;
01426 Qp = y4*Qp + q7;
01427 Qn = y4*Qn + q6;
01428 Qp = y4*Qp + q5;
01429 Qn = y4*Qn + q4;
01430 Qp = y4*Qp + q3;
01431 Qn = y4*Qn + q2;
01432 Qp = y4*Qp + q1;
01433 Qn = y4*Qn + q0;
01434 Q = Qn + y2 * Qp;
01435
01436
01437
01438
01439
01440
01441
01442
01443 k = 0x1;
01444 k = zu.zint & k;
01445
01446 where ( k == 0 ) {
01447 P = Q * y - invy;
01448 }
01449
01450 return P;
01451 }
01452 #endif
01453 #endif // Has Main
01454
01480
01481 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01482 extern math_inline double acosh(double x);
01483 #else
01484 #if defined(_uses_acosh_math_h) || !defined(__cflow_processed)
01485 math_inline double acosh(double x)
01486 {
01487 register double xr, res;
01488
01489 xr = x;
01490 res = log(xr+sqrt(xr*xr-1.0));
01491
01492 return res;
01493 }
01494 #endif
01495 #endif // Has Main
01496
01519
01520 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01521 extern math_inline double asinh(double x);
01522 #else
01523 #if defined(_uses_asinh_math_h) || !defined(__cflow_processed)
01524 math_inline double asinh(double x)
01525 {
01526 register double xr, res;
01527
01528 xr = x;
01529 res = log(xr+sqrt(xr*xr+1.0));
01530
01531 return res;
01532 }
01533 #endif
01534 #endif // Has Main
01535
01561
01562 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01563 extern math_inline double atanh(double x);
01564 #else
01565 #if defined(_uses_atanh_math_h) || !defined(__cflow_processed)
01566 math_inline double atanh(double x)
01567 {
01568 register double xr, res;
01569
01570 xr = x;
01571 res = 0.5*log( (1.0+xr)/(1.0-xr) );
01572
01573 return res;
01574 }
01575 #endif
01576 #endif // Has Main
01577
01601
01602 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01603 extern math_inline double cosh(double x);
01604 #else
01605 #if defined(_uses_cosh_math_h) || !defined(__cflow_processed)
01606 math_inline double cosh(double x)
01607 {
01608 register double xr, xm, expx, expxm, half, res;
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623 half = 0.5;
01624 xr = x;
01625 expx = exp(xr);
01626 res = 1.0/expx;
01627 res = half * (expx+res);
01628
01629 return res;
01630 }
01631 #endif
01632 #endif // Has Main
01633
01657
01658 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01659 extern math_inline double sinh(double x);
01660 #else
01661 #if defined(_uses_sinh_math_h) || !defined(__cflow_processed)
01662 math_inline double sinh(double x)
01663 {
01664 register double xr, xm, expx, expxm, half, res;
01665
01666
01667
01668
01669
01670
01671
01672
01673
01674
01675
01676
01677
01678
01679 half = 0.5;
01680 xr = x;
01681 expx = exp(xr);
01682 res = 1.0/expx;
01683 res = half * (expx - res);
01684
01685 return res;
01686 }
01687 #endif
01688 #endif // Has Main
01689
01710
01711 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01712 extern math_inline double tanh(double xxx);
01713 #else
01714 #if defined(_uses_tanh_math_h) || !defined(__cflow_processed)
01715 math_inline double tanh(double xxx)
01716 {
01717 register double x, x2, exp2x, two, temp;
01718 register double res;
01719 two = 1.0 + 1.0;
01720
01721 x = xxx;
01722 x2 = x;
01723 where ( x < 0.0 ) {
01724 x2 = -x;
01725 }
01726
01727 x2 = two * x2;
01728 exp2x = expm1(x2);
01729
01730 temp = exp2x + 2.0;
01731 temp = 1.0 / temp;
01732
01733 res = exp2x * temp;
01734 where ( x2 > two ) {
01735 res = 1.0 - two * temp;
01736 }
01737
01738 where ( x < 0.0 ) {
01739 res = - res;
01740 }
01741
01742 return res;
01743 }
01744 #endif
01745 #endif // Has Main
01746
01768
01769 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01770 extern math_inline double exp2(double x);
01771 #else
01772 #if defined(_uses_exp2_math_h) || !defined(__cflow_processed)
01773 math_inline double exp2(double x)
01774 {
01775 register double loge2,y,res;
01776
01777 loge2 = 0.69314718055994530942;
01778
01779 y = x*loge2;
01780 res = exp(y);
01781
01782 return res;
01783 }
01784 #endif
01785 #endif // Has Main
01786
01816
01817 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01818 extern math_inline double frexp(double value, int *eptr);
01819 #else
01820 #if defined(_uses_frexp_math_h) || !defined(__cflow_processed)
01821 math_inline double frexp(double value, int *eptr)
01822 {
01823 register int ptr;
01824 register uint64_t ix;
01825 register double res;
01826 register union {
01827 double zd;
01828 int zint;
01829 } z;
01830
01831 z.zd = value;
01832
01833 ix = 0x7fffffffffffffffull & z.zint;
01834
01835
01836
01837
01838
01839
01840
01841 ptr = (ix >> 52)-1022;
01842
01843 z.zint = ( (z.zint & 0x800fffffffffffff) | 0x3fe0000000000000);
01844
01845
01846
01847 *eptr = ptr;
01848 res = z.zd;
01849
01850 return res;
01851 }
01852 #endif
01853 #endif // Has Main
01854
01886
01887 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01888 extern math_inline int ilogb(double x);
01889 #else
01890 #if defined(_uses_ilogb_math_h) || !defined(__cflow_processed)
01891 math_inline int ilogb(double x)
01892 {
01893 register double xr;
01894 register uint64_t _mask;
01895 register int _sh,ie;
01896
01897 _mask=0x7FF0000000000000ULL;
01898 _sh =52;
01899
01900 xr = x;
01901 asm("\tiand.L %0 %1 %2" : "=r" (xr) : "r" (_mask) , "r" (xr) );
01902 asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (xr) , "r" (_sh) );
01903 asm("\tlutcross.H %0 %1" : "=r" (ie) : "r" (ie) );
01904 ie = ie - 0x3ff;
01905
01906 return ie;
01907 }
01908 #endif
01909 #endif // Has Main
01910
01932
01933 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01934 extern math_inline double ldexp(double x, int n);
01935 #else
01936 #if defined(_uses_ldexp_math_h) || !defined(__cflow_processed)
01937 math_inline double ldexp(double x, int n)
01938 {
01939 register double xr = 0;
01940 register int nr,_sh;
01941
01942 _sh = -52;
01943
01944 nr = n+1023;
01945 asm("\tilsh.L %0 %1 %2" : "=r" (xr) : "r" (nr) , "r" (_sh) );
01946
01947 xr = x*xr;
01948
01949 return xr;
01950 }
01951 #endif
01952 #endif // Has Main
01953
01977
01978 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
01979 extern math_inline double log10(double x);
01980 #else
01981 #if defined(_uses_log10_math_h) || !defined(__cflow_processed)
01982 math_inline double log10(double x)
01983 {
01984 register double log10e, res;
01985
01986 log10e = 0.43429448190325182765;
01987
01988 res = log(x)*log10e;
01989
01990 return res;
01991 }
01992 #endif
01993 #endif // Has Main
01994
02020
02021 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02022 extern math_inline double log1p(double xxx);
02023 #else
02024 #if defined(_uses_log1p_math_h) || !defined(__cflow_processed)
02025 math_inline double log1p(double xxx)
02026 {
02027 register double x,xx,x0,e,e1,r,r2,r4;
02028 register double P,Pa,Pb,Pc,Pd;
02029 register double trail;
02030 register double log2e,ln2lead,ln2trail,nummag ;
02031
02032 register double p0,p1,p2,p3,p4,p5,p6,p7,p8,p9;
02033 register double p10,p11,p12,p13,p14,p15,p16,p17,p18,p19;
02034 register double p20,p21,p22,p23,p24,p25,p26,p27,p28,p29;
02035 register double p30,p31,p32,p33,p34,p35,p36;
02036
02037 _math_setdouble( 0x3ff71547652b82fe, log2e );
02038 _math_setdouble( 0x3fe62e42fefa4000, ln2lead );
02039 _math_setdouble( 0xbd48432a1b0e2634, ln2trail );
02040 _math_setdouble( 0x43300000000003ff, nummag );
02041
02042
02043 _math_setdouble( 0xbfe0000000000000 , p0 );
02044 _math_setdouble( 0x3fd5555555555555 , p1 );
02045 _math_setdouble( 0xbfcfffffffffffd2 , p2 );
02046 _math_setdouble( 0x3fc9999999999944 , p3 );
02047 _math_setdouble( 0xbfc555555555839f , p4 );
02048 _math_setdouble( 0x3fc24924924994cb , p5 );
02049 _math_setdouble( 0xbfbfffffffd3792a , p6 );
02050 _math_setdouble( 0x3fbc71c71bfbb905 , p7 );
02051 _math_setdouble( 0xbfb99999a6067f7a , p8 );
02052 _math_setdouble( 0x3fb745d1960bf8dd , p9 );
02053 _math_setdouble( 0xbfb555531a405781 , p10 );
02054 _math_setdouble( 0x3fb3b1351bb667d8 , p11 );
02055 _math_setdouble( 0xbfb2496af8fbbbe4 , p12 );
02056 _math_setdouble( 0x3fb111c6afc8c6e1 , p13 );
02057 _math_setdouble( 0xbfaff38dd41057ce , p14 );
02058 _math_setdouble( 0x3fadffb7d7a94696 , p15 );
02059 _math_setdouble( 0xbfad41ba8a134738 , p16 );
02060 _math_setdouble( 0x3faccbc9726ece12 , p17 );
02061 _math_setdouble( 0xbf9ec38f119d3d06 , p18 );
02062 _math_setdouble( 0x3f785f81962a50fb , p19 );
02063 _math_setdouble( 0xbfce4be7a8a5d72b , p20 );
02064 _math_setdouble( 0x3fd9d8d252726e6c , p21 );
02065 _math_setdouble( 0x3ff5c8aa212fd722 , p22 );
02066 _math_setdouble( 0xc0026bd5ff44cd4e , p23 );
02067 _math_setdouble( 0xc01fa5187761a8ad , p24 );
02068 _math_setdouble( 0x4026d78e0bf83a6c , p25 );
02069 _math_setdouble( 0x4040ba1a1b262a4f , p26 );
02070 _math_setdouble( 0xc044570c25ae2da0 , p27 );
02071 _math_setdouble( 0xc05a8787b4194713 , p28 );
02072 _math_setdouble( 0x405a009c5d877e88 , p29 );
02073 _math_setdouble( 0x406e49c81a0007b0 , p30 );
02074 _math_setdouble( 0xc0666aa1bfe5d0fe , p31 );
02075 _math_setdouble( 0xc077926b8e4542e3 , p32 );
02076 _math_setdouble( 0x406767610205d729 , p33 );
02077 _math_setdouble( 0x40765b8a9462a4c6 , p34 );
02078 _math_setdouble( 0xc0564d5567c48d46 , p35 );
02079 _math_setdouble( 0xc06383c8abcc91fa , p36 );
02080
02081 x = xxx;
02082 xx = x + 1.0;
02083
02084 asm("\tlutmove %0 $ZERO" : "=r" (x0));
02085 asm("\tlutmove %0 $ZERO" : "=r" (e1));
02086 asm("\tlutlogm.L %0 %1" : "=r" (x0) : "r" (xx));
02087 asm("\tlutloge.L %0 %1" : "=r" (e1) : "r" (xx));
02088
02089 e = e1 - nummag;
02090 r = x0 - 1.0;
02091
02092 where ( e == 0.0 ) {
02093 r = x;
02094 }
02095
02096 r2 = r * r;
02097 r4 = r2 * r2;
02098
02099 Pa = p36;
02100 Pa = r4 * Pa + p32;
02101 Pa = r4 * Pa + p28;
02102 Pa = r4 * Pa + p24;
02103 Pa = r4 * Pa + p20;
02104 Pa = r4 * Pa + p16;
02105 Pa = r4 * Pa + p12;
02106 Pa = r4 * Pa + p8;
02107 Pa = r4 * Pa + p4;
02108 Pa = r4 * Pa + p0;
02109
02110 Pb = p33;
02111 Pb = r4 * Pb + p29;
02112 Pb = r4 * Pb + p25;
02113 Pb = r4 * Pb + p21;
02114 Pb = r4 * Pb + p17;
02115 Pb = r4 * Pb + p13;
02116 Pb = r4 * Pb + p9;
02117 Pb = r4 * Pb + p5;
02118 Pb = r4 * Pb + p1;
02119
02120 Pc = p34;
02121 Pc = r4 * Pc + p30;
02122 Pc = r4 * Pc + p26;
02123 Pc = r4 * Pc + p22;
02124 Pc = r4 * Pc + p18;
02125 Pc = r4 * Pc + p14;
02126 Pc = r4 * Pc + p10;
02127 Pc = r4 * Pc + p6;
02128 Pc = r4 * Pc + p2;
02129
02130 Pd = p35;
02131 Pd = r4 * Pd + p31;
02132 Pd = r4 * Pd + p27;
02133 Pd = r4 * Pd + p23;
02134 Pd = r4 * Pd + p19;
02135 Pd = r4 * Pd + p15;
02136 Pd = r4 * Pd + p11;
02137 Pd = r4 * Pd + p7;
02138 Pd = r4 * Pd + p3;
02139
02140 P = Pa + r * Pb + r2 * (Pc + r * Pd);
02141
02142 trail = e * ln2trail;
02143 trail = r2 * P + trail;
02144 trail = trail + r;
02145 P = trail + e * ln2lead;
02146
02147 return P;
02148 }
02149 #endif
02150 #endif // Has Main
02151
02177
02178 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02179 extern math_inline double log2(double x);
02180 #else
02181 #if defined(_uses_log2_math_h) || !defined(__cflow_processed)
02182 math_inline double log2(double x)
02183 {
02184 register double log2e, res, xr;
02185
02186 _math_setdouble( 0x3ff71547652b82fe, log2e );
02187
02188 xr = x;
02189 res = log(xr)*log2e;
02190
02191 return res;
02192 }
02193 #endif
02194 #endif // Has Main
02195
02232
02233 #if (FLT_RADIX==2)
02234 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02235 extern math_inline double logb(double x);
02236 #else
02237 #if defined(_uses_logb_math_h) || !defined(__cflow_processed)
02238 math_inline double logb(double x)
02239 {
02240 register double xr;
02241 register unsigned int _mask;
02242 register int _sh,ie;
02243
02244 _mask=0x7FF0000000000000ULL;
02245 _sh =52;
02246
02247 xr = x;
02248 asm("\tiand.L %0 %1 %2" : "=r" (xr) : "r" (_mask) , "r" (xr) );
02249 asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (xr) , "r" (_sh) );
02250 xr = ie - 0x3ff;
02251
02252 return xr;
02253 }
02254 #endif
02255 #endif // Has Main
02256 #else
02257 #error "FLT_RADIX = 2 requested"
02258 #endif
02259
02289
02290 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02291 extern math_inline double modf(double value, double *dptr);
02292 #else
02293 #if defined(_uses_modf_math_h) || !defined(__cflow_processed)
02294 math_inline double modf(double value, double *dptr)
02295 {
02296 register double y,ptr;
02297 register uint64_t _emask,_mmask,_i;
02298 register int _exp,_sh;
02299 register union {
02300 double zd;
02301 int zint;
02302 } x,z;
02303
02304 _emask = 0x7ff0000000000000ULL;
02305 _mmask = 0x000fffffffffffffULL;
02306 _sh = 52;
02307
02308 x.zd = value;
02309 _exp = ((x.zint&_emask)>>_sh)-1023;
02310
02311 where (_exp < 52) {
02312 where (_exp < 0) {
02313 ptr = 0.0;
02314 y = x.zd;
02315 } else {
02316 _i = _mmask>>_exp;
02317 where ( (x.zint&_i) == 0) {
02318 ptr = x.zd;
02319 y = 0.0;
02320 } else {
02321 z.zint = x.zint&(~_i);
02322 ptr = z.zd;
02323 y = x.zd-ptr;
02324 }
02325 }
02326 } else {
02327 ptr = x.zd;
02328 y = 0.0;
02329 }
02330
02331 *dptr = ptr;
02332 return y;
02333 }
02334 #endif
02335 #endif // Has Main
02336
02363
02364 #if (FLT_RADIX==2)
02365 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02366 extern math_inline double scalbn(double x, int n);
02367 #else
02368 #if defined(_uses_scalbn_math_h) || !defined(__cflow_processed)
02369 math_inline double scalbn(double x, int n)
02370 {
02371 register double xr;
02372 register int nr,_sh;
02373
02374 _sh = -52;
02375
02376 nr = n+1023;
02377 asm("\tilsh.L %0 %1 %2" : "=r" (xr) : "r" (nr) , "r" (_sh) );
02378
02379 xr = x*xr;
02380
02381 return xr;
02382 }
02383 #endif
02384 #endif // Has Main
02385 #else
02386 #error "FLT_RADIX = 2 requested"
02387 #endif
02388
02416
02417 #if (FLT_RADIX==2)
02418 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02419 extern math_inline double scalbln(double x, long int n);
02420 #else
02421 #if defined(_uses_scalbln_math_h) || !defined(__cflow_processed)
02422 math_inline double scalbln(double x, long int n)
02423 {
02424 register double xr;
02425 register int nr,_sh;
02426
02427 _sh = -52;
02428
02429 nr = n+1023;
02430 asm("\tilsh.L %0 %1 %2" : "=r" (xr) : "r" (nr) , "r" (_sh) );
02431
02432 xr = x*xr;
02433
02434 return xr;
02435 }
02436 #endif
02437 #endif
02438 #else
02439 #error "FLT_RADIX = 2 requested"
02440 #endif
02441
02467
02468 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02469 extern math_inline double cbrt(double x);
02470 #else
02471 #if defined(_uses_cbrt_math_h) || !defined(__cflow_processed)
02472 math_inline double cbrt(double x)
02473 {
02474 register double xr, xabs, res, one_third;
02475 _math_setdouble( 0x3fd5555555555555 , one_third);
02476
02477 xr = x;
02478 xabs = xr;
02479 where (xr < 0.0) {
02480 xabs = -xr;
02481 }
02482
02483 res = 0.0;
02484 where ( xr != 0.0) {
02485 res = exp(one_third*log(xabs));
02486 }
02487
02488 where (xr<0.0) {
02489 res = -res;
02490 }
02491
02492 return res;
02493 }
02494 #endif
02495 #endif // Has Main
02496
02525
02526 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02527 extern math_inline double fabs(double x);
02528 #else
02529 #if defined(_uses_fabs_math_h) || !defined(__cflow_processed)
02530 math_inline double fabs(double x)
02531 {
02532 register double xr, res;
02533 register uint64_t _mask;
02534
02535
02536 _mask= 0x7fffffffffffffffULL;
02537
02538 xr = x;
02539 asm("\tiand.L %0 %1 %2" : "=r" (xr) : "r" (_mask) , "r" (xr) );
02540 return xr;
02541
02542
02543
02544
02545
02546
02547
02548
02549
02550
02551
02552
02553
02554
02555
02556
02557
02558 }
02559 #endif
02560 #endif // Has Main
02561
02587
02588 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02589 extern math_inline double hypot(double x, double y);
02590 #else
02591 #if defined(_uses_hypot_math_h) || !defined(__cflow_processed)
02592 math_inline double hypot(double x, double y)
02593 {
02594 register double res;
02595
02596 res = sqrt(x*x+y*y);
02597
02598 return res;
02599 }
02600 #endif
02601 #endif // Has Main
02602
02624
02625 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02626 extern math_inline double erf(double x);
02627 #else
02628 #if defined(_uses_erf_math_h) || !defined(__cflow_processed)
02629 math_inline double erf(double x)
02630 {
02631 #ifdef __cflow_processed
02632 #error "Not yet implemented"
02633 #endif
02634 }
02635 #endif
02636 #endif // Has Main
02637
02657
02658 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02659 extern math_inline double erfc(double x);
02660 #else
02661 #if defined(_uses_erfc_math_h) || !defined(__cflow_processed)
02662 math_inline double erfc(double x)
02663 {
02664 #ifdef __cflow_processed
02665 #error "Not yet implemented"
02666 #endif
02667 }
02668 #endif
02669 #endif // Has Main
02670
02694
02695 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02696 extern math_inline double lgamma(double x);
02697 #else
02698 #if defined(_uses_lgamma_math_h) || !defined(__cflow_processed)
02699 math_inline double lgamma(double x)
02700 {
02701 #ifdef __cflow_processed
02702 #error "Not yet implemented"
02703 #endif
02704 }
02705 #endif
02706 #endif // Has Main
02707
02730
02731 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02732 extern math_inline double tgamma(double x);
02733 #else
02734 #if defined(_uses_tgamma_math_h) || !defined(__cflow_processed)
02735 math_inline double tgamma(double x)
02736 {
02737 #ifdef __cflow_processed
02738 #error "Not yet implemented"
02739 #endif
02740 }
02741 #endif
02742 #endif // Has Main
02743
02771
02772 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02773 extern math_inline double ceil(double x);
02774 #else
02775 #if defined(_uses_ceil_math_h) || !defined(__cflow_processed)
02776 math_inline double ceil(double x)
02777 {
02778 register double tmpx,res,nummag,delta;
02779
02780 _math_setdouble( 0x4330000000000000, nummag );
02781
02782 tmpx = x;
02783 where (x<0.0) {
02784 tmpx = -x;
02785 }
02786 res = ( ((tmpx+0.5)+nummag) - nummag)-1.0;
02787 delta = tmpx - res;
02788 where (delta >= 1.0) {
02789 res = res + 1.0;
02790 }
02791 where (x<0.0) {
02792 res = -res;
02793 }
02794 where (res < x) {
02795 res = res + 1.0;
02796 }
02797
02798 return res;
02799 }
02800 #endif
02801 #endif // Has Main
02802
02830
02831 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02832 extern math_inline double floor(double x);
02833 #else
02834 #if defined(_uses_floor_math_h) || !defined(__cflow_processed)
02835 math_inline double floor(double x)
02836 {
02837 register double tmpx,res,nummag,delta;
02838
02839 _math_setdouble( 0x4330000000000000, nummag );
02840
02841 tmpx = x;
02842 where (x<0.0) {
02843 tmpx = -x;
02844 }
02845 res = ( ((tmpx+0.5)+nummag) - nummag)-1.0;
02846 delta = tmpx - res;
02847 where (delta >= 1.0) {
02848 res = res + 1.0;
02849 }
02850 where (x<0.0) {
02851 res = -res;
02852 }
02853 where (res > x) {
02854 res = res - 1.0;
02855 }
02856
02857 return res;
02858 }
02859 #endif
02860 #endif // Has Main
02861
02901
02902 #if (FLT_ROUNDS==1)
02903 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02904 extern math_inline double nearbyint(double x);
02905 #else
02906 #if defined(_uses_nearbyint_math_h) || !defined(__cflow_processed)
02907 math_inline double nearbyint(double x)
02908 {
02909 register double res;
02910
02911 where (x>0.0) {
02912 res = floor(x);
02913 where ( (x-res) >= 0.5 ) {
02914 res = res + 1.0;
02915 }
02916 } else {
02917 res = ceil(x);
02918 where ( (res-x) >= 0.5 ) {
02919 res = res - 1.0;
02920 }
02921 }
02922
02923 return res;
02924 }
02925 #endif
02926 #endif // Has Main
02927 #else
02928 #error "FLT_ROUNDS = 1 expected"
02929 #endif
02930
02957
02958 #if (FLT_ROUNDS==1)
02959 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02960 extern math_inline double rint(double x);
02961 #else
02962 #if defined(_uses_rint_math_h) || !defined(__cflow_processed)
02963 math_inline double rint(double x)
02964 {
02965 register double res;
02966
02967 where (x>0.0) {
02968 res = floor(x);
02969 where ( (x-res) >= 0.5 ) {
02970 res = res + 1.0;
02971 }
02972 } else {
02973 res = ceil(x);
02974 where ( (res-x) >= 0.5 ) {
02975 res = res - 1.0;
02976 }
02977 }
02978
02979 return res;
02980 }
02981 #endif
02982 #endif // Has Main
02983 #else
02984 #error "FLT_ROUNDS = 1 expected"
02985 #endif
02986
03018
03019 #if (FLT_ROUNDS==1)
03020 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03021 extern math_inline long int lrint(double x);
03022 #else
03023 #if defined(_uses_lrint_math_h) || !defined(__cflow_processed)
03024 math_inline long int lrint(double x)
03025 {
03026 register double res;
03027 register long int res_i;
03028
03029 where (x>0.0) {
03030 res = floor(x);
03031 where ( (x-res) >= 0.5 ) {
03032 res = res + 1.0;
03033 }
03034 } else {
03035 res = ceil(x);
03036 where ( (res-x) >= 0.5 ) {
03037 res = res - 1.0;
03038 }
03039 }
03040
03041 res_i = res;
03042 return res_i;
03043 }
03044 #endif // Has Main
03045 #endif
03046 #else
03047 #error "FLT_ROUNDS = 1 expected"
03048 #endif
03049
03080
03081 #define llrint(x) lrint(x)
03082
03110
03111 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03112 extern math_inline double round(double x);
03113 #else
03114 #if defined(_uses_round_math_h) || !defined(__cflow_processed)
03115 math_inline double round(double x)
03116 {
03117 register double res;
03118
03119 where (x>0.0) {
03120 res = floor(x);
03121 where ( (x-res) >= 0.5 ) {
03122 res = res + 1.0;
03123 }
03124 } else {
03125 res = ceil(x);
03126 where ( (res-x) >= 0.5 ) {
03127 res = res - 1.0;
03128 }
03129 }
03130
03131 return res;
03132 }
03133 #endif
03134 #endif // Has Main
03135
03167
03168 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03169 extern math_inline long int lround(double x);
03170 #else
03171 #if defined(_uses_lround_math_h) || !defined(__cflow_processed)
03172 math_inline long int lround(double x)
03173 {
03174 register double res;
03175 register long int res_i;
03176
03177 where (x>0.0) {
03178 res = floor(x);
03179 where ( (x-res) >= 0.5 ) {
03180 res = res + 1.0;
03181 }
03182 } else {
03183 res = ceil(x);
03184 where ( (res-x) >= 0.5 ) {
03185 res = res - 1.0;
03186 }
03187 }
03188
03189 res_i = res;
03190 return res_i;
03191 }
03192 #endif
03193 #endif // Has Main
03194
03225
03226 #define llround(x) lround(x)
03227
03272
03273 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03274 extern math_inline double trunc(double x);
03275 #else
03276 #if defined(_uses_trunc_math_h) || !defined(__cflow_processed)
03277 math_inline double trunc(double x)
03278 {
03279 register double tmpx,res,nummag,delta;
03280
03281
03282
03283
03284
03285
03286
03287
03288
03289
03290
03291
03292
03293
03294
03295
03296
03297
03298
03299
03300 register double xr,tmp;
03301 register uint64_t _emask;
03302 register int _sh,ie;
03303
03304 _emask=0x7FF0000000000000ULL;
03305 _sh =52;
03306
03307 xr = x;
03308
03309 asm("\tiand.L %0 %1 %2" : "=r" (tmp) : "r" (_emask) , "r" (xr) );
03310
03311 asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (tmp) , "r" (_sh) );
03312
03313 ie = ie - 0x3ff;
03314
03315
03316 if( ie < 0 ) {
03317 double rv;
03318 asm("\tiand %R0 %1 %2\n\tior %0 $ZERO %R0" : "=r" (rv) : "r" (x), "r" (0x8000000000000000ULL));
03319 return rv;
03320 }
03321 _sh = _sh - ie;
03322 asm("\tilsh.L %0 %1 %2" : "=r" (xr) : "r" (xr) , "r" (_sh) );
03323 _sh = -_sh;
03324 asm("\tilsh.L %0 %1 %2" : "=r" (res) : "r" (xr) , "r" (_sh) );
03325
03326 return res;
03327 }
03328 #endif
03329 #endif // Has Main
03330
03360
03361 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03362 extern math_inline double copysign(double x, double y);
03363 #else
03364 #if defined(_uses_copysign_math_h) || !defined(__cflow_processed)
03365 math_inline double copysign(double x, double y)
03366 {
03367 register uint64_t _smask;
03368 register double res;
03369 register union {
03370 double zd;
03371 int zint;
03372 } _x,_y,z;
03373
03374 _smask = 0x8000000000000000ULL;
03375
03376 _x.zd = x;
03377 _y.zd = y;
03378
03379
03380 _x.zint &= ~_smask;
03381 _y.zint &= _smask;
03382
03383
03384 _x.zint |= _y.zint;
03385
03386
03387 z.zint = _x.zint;
03388 res = z.zd;
03389
03390 return res;
03391 }
03392 #endif
03393 #endif // Has Main
03394
03422
03423 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03424 extern math_inline double fmod(double x, double y);
03425 #else
03426 #if defined(_uses_fmod_math_h) || !defined(__cflow_processed)
03427 math_inline double fmod(double x, double y)
03428 {
03429 register double ratio,res;
03430
03431 ratio = x/y;
03432 res = x - trunc(ratio) * y;
03433
03434 return res;
03435 }
03436 #endif
03437 #endif // Has Main
03438
03469
03470 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03471 extern math_inline double remainder(double x, double y);
03472 #else
03473 #if defined(_uses_remainder_math_h) || !defined(__cflow_processed)
03474 math_inline double remainder(double x, double y)
03475 {
03476 register double res, ratio, n, two, two_c;
03477
03478
03479
03480
03481
03482
03483 two = 1.0 + 1.0;
03484 ratio = x/y;
03485 n = round(ratio);
03486 two_c = fmod(n,two);
03487
03488 where ( fabs(n-ratio) == 0.5 ) {
03489 n = n - two_c;
03490 }
03491
03492 res = x - n * y;
03493
03494 return res;
03495 }
03496 #endif
03497 #endif // Has Main
03498
03525
03526 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03527 extern math_inline double remquo(double x, double y, int *quo);
03528 #else
03529 #if defined(_uses_remquo_math_h) || !defined(__cflow_processed)
03530 math_inline double remquo(double x, double y, int *quo)
03531 {
03532 register double res,ratio,eight,dquo;
03533 register int iquo;
03534 eight = 8.0;
03535
03536 res = remainder(x,y);
03537
03538 ratio = trunc(x/y);
03539 dquo = fmod(ratio,eight);
03540 dquo = copysign(dquo,ratio);
03541 iquo = dquo;
03542 *quo = iquo;
03543
03544 return res;
03545 }
03546 #endif
03547 #endif // Has Main
03548
03577
03578 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03579 extern math_inline double nan(const char *tagp);
03580 #else
03581 #if defined(_uses_nan_math_h) || !defined(__cflow_processed)
03582 math_inline double nan(const char *tagp)
03583 {
03584 #ifdef __cflow_processed
03585 # warning "nan(): NaN and Infinity are not supported by ApeNEXT. Generates systematically an exception."
03586 #endif
03587 return 0;
03588 }
03589 #endif
03590 #endif // Has Main
03591
03621
03622 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03623 extern math_inline double nextafter(double x, double y);
03624 #else
03625 #if defined(_uses_nextafter_math_h) || !defined(__cflow_processed)
03626 math_inline double nextafter(double x, double y)
03627 {
03628 register double xr,yr,res;
03629 register unsigned int ix,_lastbitmask;
03630 register union {
03631 double zd;
03632 int zint;
03633 } z;
03634
03635 _lastbitmask = 0x0000000000000001ULL;
03636
03637 xr = x;
03638 yr = y;
03639 z.zd = xr;
03640 ix = z.zint;
03641
03642
03643 where (xr != yr) {
03644 where (x==0.0) {
03645 z.zint = _lastbitmask;
03646 res = copysign(z.zd,yr);
03647 } else {
03648 where ( ((xr>0.0)&&(yr>xr)) \
03649 ||((xr<0.0)&&(yr<xr)) ) {
03650 z.zint = ix + _lastbitmask;
03651 }
03652 else {
03653 z.zint = ix - _lastbitmask;
03654 }
03655 res = z.zd;
03656 }
03657 } else {
03658 res = yr;
03659 }
03660
03661
03662 return res;
03663 }
03664 #endif
03665 #endif // Has Main
03666
03694
03695
03696 #define nexttoward(x,y) nextafter(x,y)
03697
03729
03730 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03731 extern math_inline double pow(double x, double y);
03732 #else
03733 #if defined(_uses_pow_math_h) || !defined(__cflow_processed)
03734 math_inline double pow(double x, double y)
03735 {
03736 register double tmp_y,tmp_x,res,sign,two;
03737 register int tmp_i;
03738 register double tmp;
03739 register uint64_t _emask;
03740 register int _sh,ie;
03741
03742 asm("\n\t!!-- begin pow()");
03743 res = 0.0;
03744
03745
03746
03747
03748
03749
03750
03751
03752
03753
03754
03755
03756
03757
03758
03759
03760
03761
03762
03763
03764
03765
03766 sign = 1.0;
03767 tmp_x = x;
03768 tmp_y = y;
03769 where (tmp_x < 0.0) {
03770 tmp_x = -tmp_x;
03771
03772
03773
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784 _emask=0x7FF0000000000000ULL;
03785 _sh =52;
03786
03787
03788 asm("\tiand.L %0 %1 %2" : "=r" (tmp) : "r" (_emask) , "r" (tmp_y) );
03789 asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (tmp) , "r" (_sh) );
03790 ie = ie - 0x400;
03791 _sh = _sh - ie;
03792 where( ie < 0 ){
03793 tmp = 0;
03794 } else {
03795 asm("\tilsh.L %0 %1 %2" : "=r" (tmp) : "r" (tmp_y) , "r" (_sh) );
03796 _sh = -_sh;
03797 asm("\tilsh.L %0 %1 %2" : "=r" (tmp) : "r" (tmp) , "r" (_sh) );
03798 }
03799
03800
03801 tmp = tmp_y - tmp;
03802 where (tmp != 0.0) {
03803
03804 res = ((union { unsigned u; double d; }){.u=0x7ff0100000000000ULL}).d;
03805 where ( (tmp == 1.0) || (tmp == -1.0) )
03806 {
03807 sign = -1.0;
03808 }
03809 else
03810 tmp_x = 0.0;
03811 }
03812 }
03813
03814 where (tmp_x != 0.0) {
03815 res = sign*exp(y*log(tmp_x));
03816 }
03817 else
03818 where (y==0.0)
03819 res=1.0;
03820
03821 asm("\t!!-- end pow()\n");
03822 return res;
03823 }
03824 #endif
03825 #endif // Has Main
03826
03851
03852 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03853 extern math_inline double fdim(double x, double y);
03854 #else
03855 #if defined(_uses_fdim_math_h) || !defined(__cflow_processed)
03856 math_inline double fdim(double x, double y)
03857 {
03858 register double res;
03859
03860 where( x > y ) {
03861 res = x - y;
03862 } else {
03863 res = 0;
03864 }
03865 return res;
03866 }
03867 #endif
03868 #endif // Has Main
03869
03894
03895 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03896 extern math_inline double fmax(double x, double y);
03897 #else
03898 #if defined(_uses_fmax_math_h) || !defined(__cflow_processed)
03899 math_inline double fmax(double x, double y)
03900 {
03901 register double res;
03902
03903 where( x > y ) {
03904 res = x;
03905 } else {
03906 res = y;
03907 }
03908 return res;
03909 }
03910 #endif
03911 #endif // Has Main
03912
03936
03937 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03938 extern math_inline double fmin(double x, double y);
03939 #else
03940 #if defined(_uses_fmin_math_h) || !defined(__cflow_processed)
03941 math_inline double fmin(double x, double y)
03942 {
03943 register double res;
03944
03945 where( x < y ) {
03946 res = x;
03947 } else {
03948 res = y;
03949 }
03950 return res;
03951 }
03952 #endif
03953 #endif // Has Main
03954
03977
03978 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03979 extern math_inline double fma(double x, double y, double z);
03980 #else
03981 #if defined(_uses_fma_math_h) || !defined(__cflow_processed)
03982 math_inline double fma(double x, double y, double z)
03983 {
03984 register double res;
03985
03986 res = x*y + z;
03987
03988 return res;
03989 }
03990 #endif
03991 #endif // Has Main
03992
04019
04020 #define isgreater(x,y) _isgreater(x,y)
04021
04048
04049 #define isgreaterequal(x,y) _isgreaterequal(x,y)
04050
04077
04078 #define isless(x,y) _isless(x,y)
04079
04106
04107 #define islessequal(x,y) _islessequal(x,y)
04108
04134
04135 #define islessgreater(x,y) _islessgreater(x,y)
04136
04160
04161 #define isunordered( x, y) _isunordered( x, y)
04162
04188 #undef _math_setdouble
04189 #endif