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
02781 _math_setdouble( 0x4337ffffffffffff, nummag );
02782
02783 tmpx = x;
02784 res = ( (tmpx+nummag) - nummag);
02785 where (res < x) {
02786 res = res + 1.0;
02787 }
02788
02789
02790
02791
02792
02793
02794
02795
02796
02797
02798
02799
02800
02801
02802
02803
02804
02805
02806
02807
02808
02809 return res;
02810 }
02811 #endif
02812 #endif // Has Main
02813
02841
02842 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02843 extern math_inline double floor(double x);
02844 #else
02845 #if defined(_uses_floor_math_h) || !defined(__cflow_processed)
02846 math_inline double floor(double x)
02847 {
02848 register double tmpx,res,nummag;
02849
02850
02851 _math_setdouble( 0x4330000000000000, nummag );
02852
02853 tmpx = x;
02854 res = (tmpx+nummag) - nummag;
02855 where (res > x) {
02856 res = res - 1.0;
02857 }
02858
02859
02860
02861
02862
02863
02864
02865
02866
02867
02868
02869
02870
02871
02872
02873
02874
02875
02876
02877
02878
02879 return res;
02880 }
02881 #endif
02882 #endif // Has Main
02883
02923
02924 #if (FLT_ROUNDS==1)
02925 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02926 extern math_inline double nearbyint(double x);
02927 #else
02928 #if defined(_uses_nearbyint_math_h) || !defined(__cflow_processed)
02929 math_inline double nearbyint(double x)
02930 {
02931 register double res;
02932
02933 where (x>0.0) {
02934 res = floor(x);
02935 where ( (x-res) >= 0.5 ) {
02936 res = res + 1.0;
02937 }
02938 } else {
02939 res = ceil(x);
02940 where ( (res-x) >= 0.5 ) {
02941 res = res - 1.0;
02942 }
02943 }
02944
02945 return res;
02946 }
02947 #endif
02948 #endif // Has Main
02949 #else
02950 #error "FLT_ROUNDS = 1 expected"
02951 #endif
02952
02979
02980 #if (FLT_ROUNDS==1)
02981 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
02982 extern math_inline double rint(double x);
02983 #else
02984 #if defined(_uses_rint_math_h) || !defined(__cflow_processed)
02985 math_inline double rint(double x)
02986 {
02987 register double res;
02988
02989 where (x>0.0) {
02990 res = floor(x);
02991 where ( (x-res) >= 0.5 ) {
02992 res = res + 1.0;
02993 }
02994 } else {
02995 res = ceil(x);
02996 where ( (res-x) >= 0.5 ) {
02997 res = res - 1.0;
02998 }
02999 }
03000
03001 return res;
03002 }
03003 #endif
03004 #endif // Has Main
03005 #else
03006 #error "FLT_ROUNDS = 1 expected"
03007 #endif
03008
03040
03041 #if (FLT_ROUNDS==1)
03042 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03043 extern math_inline long int lrint(double x);
03044 #else
03045 #if defined(_uses_lrint_math_h) || !defined(__cflow_processed)
03046 math_inline long int lrint(double x)
03047 {
03048 register double res;
03049 register long int res_i;
03050
03051 where (x>0.0) {
03052 res = floor(x);
03053 where ( (x-res) >= 0.5 ) {
03054 res = res + 1.0;
03055 }
03056 } else {
03057 res = ceil(x);
03058 where ( (res-x) >= 0.5 ) {
03059 res = res - 1.0;
03060 }
03061 }
03062
03063 res_i = res;
03064 return res_i;
03065 }
03066 #endif // Has Main
03067 #endif
03068 #else
03069 #error "FLT_ROUNDS = 1 expected"
03070 #endif
03071
03102
03103 #define llrint(x) lrint(x)
03104
03132
03133 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03134 extern math_inline double round(double x);
03135 #else
03136 #if defined(_uses_round_math_h) || !defined(__cflow_processed)
03137 math_inline double round(double x)
03138 {
03139 register double res,tmpx,nummag;
03140
03141
03142
03143
03144
03145
03146
03147
03148
03149 where (x>0.0) {
03150 res = floor(x);
03151 where ( (x-res) >= 0.5 ) {
03152 res = res + 1.0;
03153 }
03154 } else {
03155 res = ceil(x);
03156 where ( (res-x) >= 0.5 ) {
03157 res = res - 1.0;
03158 }
03159 }
03160
03161 return res;
03162 }
03163 #endif
03164 #endif // Has Main
03165
03197
03198 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03199 extern math_inline long int lround(double x);
03200 #else
03201 #if defined(_uses_lround_math_h) || !defined(__cflow_processed)
03202 math_inline long int lround(double x)
03203 {
03204 register double res;
03205 register long int res_i;
03206
03207 where (x>0.0) {
03208 res = floor(x);
03209 where ( (x-res) >= 0.5 ) {
03210 res = res + 1.0;
03211 }
03212 } else {
03213 res = ceil(x);
03214 where ( (res-x) >= 0.5 ) {
03215 res = res - 1.0;
03216 }
03217 }
03218
03219 res_i = res;
03220 return res_i;
03221 }
03222 #endif
03223 #endif // Has Main
03224
03255
03256 #define llround(x) lround(x)
03257
03302
03303 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03304 extern math_inline double trunc(double x);
03305 #else
03306 #if defined(_uses_trunc_math_h) || !defined(__cflow_processed)
03307 math_inline double trunc(double x)
03308 {
03309 register double tmpx,res,nummag,delta;
03310
03311
03312
03313
03314
03315
03316
03317
03318
03319
03320
03321
03322
03323
03324
03325
03326
03327
03328
03329
03330 register double xr,tmp;
03331 register uint64_t _emask;
03332 register int _sh,ie;
03333
03334 _emask=0x7FF0000000000000ULL;
03335 _sh =52;
03336
03337 xr = x;
03338
03339 asm("\tiand.L %0 %1 %2" : "=r" (tmp) : "r" (_emask) , "r" (xr) );
03340
03341 asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (tmp) , "r" (_sh) );
03342
03343 ie = ie - 0x3ff;
03344
03345
03346 if( ie < 0 ) {
03347 double rv;
03348 asm("\tiand %R0 %1 %2\n\tior %0 $ZERO %R0" : "=r" (rv) : "r" (x), "r" (0x8000000000000000ULL));
03349 return rv;
03350 }
03351 _sh = _sh - ie;
03352 asm("\tilsh.L %0 %1 %2" : "=r" (xr) : "r" (xr) , "r" (_sh) );
03353 _sh = -_sh;
03354 asm("\tilsh.L %0 %1 %2" : "=r" (res) : "r" (xr) , "r" (_sh) );
03355
03356 return res;
03357 }
03358 #endif
03359 #endif // Has Main
03360
03390
03391 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03392 extern math_inline double copysign(double x, double y);
03393 #else
03394 #if defined(_uses_copysign_math_h) || !defined(__cflow_processed)
03395 math_inline double copysign(double x, double y)
03396 {
03397 register uint64_t _smask;
03398 register double res;
03399 register union {
03400 double zd;
03401 int zint;
03402 } _x,_y,z;
03403
03404 _smask = 0x8000000000000000ULL;
03405
03406 _x.zd = x;
03407 _y.zd = y;
03408
03409
03410 _x.zint &= ~_smask;
03411 _y.zint &= _smask;
03412
03413
03414 _x.zint |= _y.zint;
03415
03416
03417 z.zint = _x.zint;
03418 res = z.zd;
03419
03420 return res;
03421 }
03422 #endif
03423 #endif // Has Main
03424
03452
03453 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03454 extern math_inline double fmod(double x, double y);
03455 #else
03456 #if defined(_uses_fmod_math_h) || !defined(__cflow_processed)
03457 math_inline double fmod(double x, double y)
03458 {
03459 register double ratio,res;
03460
03461 ratio = x/y;
03462 res = x - trunc(ratio) * y;
03463
03464 return res;
03465 }
03466 #endif
03467 #endif // Has Main
03468
03499
03500 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03501 extern math_inline double remainder(double x, double y);
03502 #else
03503 #if defined(_uses_remainder_math_h) || !defined(__cflow_processed)
03504 math_inline double remainder(double x, double y)
03505 {
03506 register double res, ratio, n, two, two_c;
03507
03508
03509
03510
03511
03512
03513 two = 1.0 + 1.0;
03514 ratio = x/y;
03515 n = round(ratio);
03516 two_c = fmod(n,two);
03517
03518 where ( fabs(n-ratio) == 0.5 ) {
03519 n = n - two_c;
03520 }
03521
03522 res = x - n * y;
03523
03524 return res;
03525 }
03526 #endif
03527 #endif // Has Main
03528
03555
03556 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03557 extern math_inline double remquo(double x, double y, int *quo);
03558 #else
03559 #if defined(_uses_remquo_math_h) || !defined(__cflow_processed)
03560 math_inline double remquo(double x, double y, int *quo)
03561 {
03562 register double res,ratio,eight,dquo;
03563 register int iquo;
03564 eight = 8.0;
03565
03566 res = remainder(x,y);
03567
03568 ratio = trunc(x/y);
03569 dquo = fmod(ratio,eight);
03570 dquo = copysign(dquo,ratio);
03571 iquo = dquo;
03572 *quo = iquo;
03573
03574 return res;
03575 }
03576 #endif
03577 #endif // Has Main
03578
03607
03608 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03609 extern math_inline double nan(const char *tagp);
03610 #else
03611 #if defined(_uses_nan_math_h) || !defined(__cflow_processed)
03612 math_inline double nan(const char *tagp)
03613 {
03614 #ifdef __cflow_processed
03615 # warning "nan(): NaN and Infinity are not supported by ApeNEXT. Generates systematically an exception."
03616 #endif
03617 return 0;
03618 }
03619 #endif
03620 #endif // Has Main
03621
03651
03652 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03653 extern math_inline double nextafter(double x, double y);
03654 #else
03655 #if defined(_uses_nextafter_math_h) || !defined(__cflow_processed)
03656 math_inline double nextafter(double x, double y)
03657 {
03658 register double xr,yr,res;
03659 register unsigned int ix,_lastbitmask;
03660 register union {
03661 double zd;
03662 int zint;
03663 } z;
03664
03665 _lastbitmask = 0x0000000000000001ULL;
03666
03667 xr = x;
03668 yr = y;
03669 z.zd = xr;
03670 ix = z.zint;
03671
03672
03673 where (xr != yr) {
03674 where (x==0.0) {
03675 z.zint = _lastbitmask;
03676 res = copysign(z.zd,yr);
03677 } else {
03678 where ( ((xr>0.0)&&(yr>xr)) \
03679 ||((xr<0.0)&&(yr<xr)) ) {
03680 z.zint = ix + _lastbitmask;
03681 }
03682 else {
03683 z.zint = ix - _lastbitmask;
03684 }
03685 res = z.zd;
03686 }
03687 } else {
03688 res = yr;
03689 }
03690
03691
03692 return res;
03693 }
03694 #endif
03695 #endif // Has Main
03696
03724
03725
03726 #define nexttoward(x,y) nextafter(x,y)
03727
03759
03760 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03761 extern math_inline double pow(double x, double y);
03762 #else
03763 #if defined(_uses_pow_math_h) || !defined(__cflow_processed)
03764 math_inline double pow(double x, double y)
03765 {
03766 register double tmp_y,tmp_x,res,sign,two;
03767 register int tmp_i;
03768 register double tmp;
03769 register uint64_t _emask;
03770 register int _sh,ie;
03771
03772 asm("\n\t!!-- begin pow()");
03773 res = 0.0;
03774
03775
03776
03777
03778
03779
03780
03781
03782
03783
03784
03785
03786
03787
03788
03789
03790
03791
03792
03793
03794
03795
03796 sign = 1.0;
03797 tmp_x = x;
03798 tmp_y = y;
03799 where (tmp_x < 0.0) {
03800 tmp_x = -tmp_x;
03801
03802
03803
03804
03805
03806
03807
03808
03809
03810
03811
03812
03813
03814 _emask=0x7FF0000000000000ULL;
03815 _sh =52;
03816
03817
03818 asm("\tiand.L %0 %1 %2" : "=r" (tmp) : "r" (_emask) , "r" (tmp_y) );
03819 asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (tmp) , "r" (_sh) );
03820 ie = ie - 0x400;
03821 _sh = _sh - ie;
03822 where( ie < 0 ){
03823 tmp = 0;
03824 } else {
03825 asm("\tilsh.L %0 %1 %2" : "=r" (tmp) : "r" (tmp_y) , "r" (_sh) );
03826 _sh = -_sh;
03827 asm("\tilsh.L %0 %1 %2" : "=r" (tmp) : "r" (tmp) , "r" (_sh) );
03828 }
03829
03830
03831 tmp = tmp_y - tmp;
03832 where (tmp != 0.0) {
03833
03834 res = ((union { unsigned u; double d; }){.u=0x7ff0100000000000ULL}).d;
03835 where ( (tmp == 1.0) || (tmp == -1.0) )
03836 {
03837 sign = -1.0;
03838 }
03839 else
03840 tmp_x = 0.0;
03841 }
03842 }
03843
03844 where (tmp_x != 0.0) {
03845 res = sign*exp(y*log(tmp_x));
03846 }
03847 else
03848 where (y==0.0)
03849 res=1.0;
03850
03851 asm("\t!!-- end pow()\n");
03852 return res;
03853 }
03854 #endif
03855 #endif // Has Main
03856
03881
03882 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03883 extern math_inline double fdim(double x, double y);
03884 #else
03885 #if defined(_uses_fdim_math_h) || !defined(__cflow_processed)
03886 math_inline double fdim(double x, double y)
03887 {
03888 register double res;
03889
03890 where( x > y ) {
03891 res = x - y;
03892 } else {
03893 res = 0;
03894 }
03895 return res;
03896 }
03897 #endif
03898 #endif // Has Main
03899
03924
03925 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03926 extern math_inline double fmax(double x, double y);
03927 #else
03928 #if defined(_uses_fmax_math_h) || !defined(__cflow_processed)
03929 math_inline double fmax(double x, double y)
03930 {
03931 register double res;
03932
03933 where( x > y ) {
03934 res = x;
03935 } else {
03936 res = y;
03937 }
03938 return res;
03939 }
03940 #endif
03941 #endif // Has Main
03942
03966
03967 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
03968 extern math_inline double fmin(double x, double y);
03969 #else
03970 #if defined(_uses_fmin_math_h) || !defined(__cflow_processed)
03971 math_inline double fmin(double x, double y)
03972 {
03973 register double res;
03974
03975 where( x < y ) {
03976 res = x;
03977 } else {
03978 res = y;
03979 }
03980 return res;
03981 }
03982 #endif
03983 #endif // Has Main
03984
04007
04008 #if !defined(__HAS_MAIN) && !defined(_INLINE_MATH_)
04009 extern math_inline double fma(double x, double y, double z);
04010 #else
04011 #if defined(_uses_fma_math_h) || !defined(__cflow_processed)
04012 math_inline double fma(double x, double y, double z)
04013 {
04014 register double res;
04015
04016 res = x*y + z;
04017
04018 return res;
04019 }
04020 #endif
04021 #endif // Has Main
04022
04049
04050 #define isgreater(x,y) _isgreater(x,y)
04051
04078
04079 #define isgreaterequal(x,y) _isgreaterequal(x,y)
04080
04107
04108 #define isless(x,y) _isless(x,y)
04109
04136
04137 #define islessequal(x,y) _islessequal(x,y)
04138
04164
04165 #define islessgreater(x,y) _islessgreater(x,y)
04166
04190
04191 #define isunordered( x, y) _isunordered( x, y)
04192
04218 #undef _math_setdouble
04219 #endif