Main Page | Alphabetical List | Class List | File List | Class Members | File Members

math.h

Go to the documentation of this file.
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 /*  old version 
00057 #define _math_setdouble(U,D) { \
00058   register union { double d; unsigned i; } u; \
00059   u.i=U; D=u.d; \
00060 }
00061 */
00062 
00063 #include <stdint.h>
00064 #include <limits.h>
00065 #include <float.h>
00066 
00067 
00068 /* ++++++++++++        macros       +++++++++++++++++++*/
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 /* #define isinf(x) (int) ( !(0x7ff != ((0x7FF0000000000000ULL & (*((unsigned int *)(&x))))>>52) ) )
00246    der geht wenn auf integer zugewiesen, aber nicht in where */
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);   // 0.5
00363     _math_setdouble(0x3FF8000000000000,three_half); // 1.5
00364 
00365     aR = a;
00366     ris = 0.0;
00367 /*  where ( aR>0.0 ) {   // avoids exception if x<0  */
00368     where ( aR ) {       // original 
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     // -- Remez coefficients for log -------------------------------
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     // -- Remez coefficients for exp -------------------------------
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     // -- Remez coefficients for exp -------------------------------
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;  // replace by pilead,pitrail ? /
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 ) {  // "<=" takes care of x<0, y=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     // Compute the sin and the cos of (y)
01142 
01143     siny = sin_1oct(y);
01144     cosy = cos_1oct(y);
01145 
01146     /* -----------------------------------------
01147     !! get the module 4 of _f  The modul is get
01148     !! over z that has mantissa _f+0x7fff...f
01149     !! That means _k = (_f%4 + 3)%4
01150     !! _f = 0 -> _k= 3
01151     !! _f = 1 -> _k= 0
01152     !! _f = 2 -> _k= 1
01153     !! _f = 3 -> _k= 2
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     // Compute the sin and the cos of y for (-pi/4<y<pi/4)
01232     // -----------------------------------------
01233 
01234     siny = sin_1oct(y);
01235     cosy = cos_1oct(y);
01236 
01237     /* -----------------------------------------
01238     !! get the module 4 of _f  The modul is get
01239     !! over z that has mantissa _f+0x7fff...f
01240     !! That means _k = (f%4 + 3)%4
01241     !! f = 0 -> k= 3
01242     !! f = 1 -> k= 0
01243     !! f = 2 -> k= 1
01244     !! f = 3 -> k= 2
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     // -- Remez coefficients for tan -------------------------------
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     // -- Remez coefficients for cotan -------------------------------
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     !! get the module 2 of f  The modul is get
01438     !! over z that has mantissa f+0x7fff...f
01439     !! That means k = (f%2 + 1)%2
01440     !! f = 0 -> k= 1
01441     !! f = 1 -> k= 0
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 /* version 1 */
01611 /*
01612     half = 0.5;
01613     xr =   x;
01614     xm = - xr;
01615 
01616     expx  = expm1( xr );
01617     expxm = expm1( xm );
01618 
01619     res = half * expx + half * expxm + 1.0;
01620 */
01621 
01622 /* version 2 */
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 /* version 1 */
01667 /* 
01668     half = 0.5;
01669     xr =   x;
01670     xm = - xr;
01671 
01672     expx  = expm1(xr);
01673     expxm = expm1(xm);
01674 
01675     res = half * (expx - expxm);
01676 */
01677 
01678 /* version 1 */
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                                                        // write_int(hx);
01833         ix = 0x7fffffffffffffffull & z.zint;           // strip sign
01834                                                        // write_int(ix);
01835 /*      *eptr = 0;
01836 
01837         where (ix >= 0x7ff0000000000000 || (ix==0)) {
01838            return x;                                   // 0,inf,nan
01839         }
01840 */
01841         ptr = (ix >> 52)-1022;                         // exponent+1
01842                                                        // write_int(hx);
01843         z.zint = ( (z.zint & 0x800fffffffffffff) | 0x3fe0000000000000);
01844                                                        // sign plus mantissa
01845                                                        // normalize and divide by 2
01846                                                        // write_int(hx);
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     // -- Remez coefficients for log -------------------------------
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;        // exponent of x
02310                                              // write_int(_exp);
02311   where (_exp < 52) {                        // chance of fractional part
02312        where (_exp < 0) {                    // |x| < 1
02313             ptr = 0.0;                       // correct for sign ? (+-0?)
02314             y = x.zd;
02315        } else {
02316             _i = _mmask>>_exp;
02317             where ( (x.zint&_i) == 0) {         // x is integer
02318                  ptr = x.zd;
02319                  y     = 0.0;                // correct sign ? (+-0?)
02320             } else {
02321                  z.zint = x.zint&(~_i);
02322                  ptr = z.zd;
02323                  y = x.zd-ptr;
02324             }
02325        }
02326   } else {                                   // no fractional part
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 /* version 1 */
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 /* version 2 */ 
02543 /*
02544   xr = x;
02545   where( xr < 0.0 ) {
02546     xr = -xr;
02547   } 
02548   return xr;
02549 */
02550 
02551 /* version 3 */ 
02552 /*
02553   xr = x;
02554   asm("\tfnorm_ap %0 $F_ONE %1 $ZERO" : "=r" (res) : "r" (xr));
02555   return res;
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 /* old version
02790     _math_setdouble(  0x4330000000000000, nummag   );
02791 
02792     tmpx = x;
02793     where (x<0.0) {
02794           tmpx = -x;
02795     }
02796     res = ( ((tmpx+0.5)+nummag) - nummag)-1.0; 
02797     delta = tmpx - res;
02798     where (delta >= 1.0) {
02799           res = res + 1.0;
02800     }
02801     where (x<0.0) {
02802           res = -res;
02803     } 
02804     where (res < x) {
02805           res = res + 1.0;
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 //    _math_setdouble(  0x4337ffffffffffff, nummag   );
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 /* old version
02860     _math_setdouble(  0x4330000000000000, nummag   );
02861 
02862     tmpx = x;
02863     where (x<0.0) {
02864           tmpx = -x;
02865     }
02866     res = ( ((tmpx+0.5)+nummag) - nummag)-1.0; 
02867     delta = tmpx - res;
02868     where (delta >= 1.0) {
02869           res = res + 1.0;
02870     }
02871     where (x<0.0) {
02872           res = -res;
02873     } 
02874     where (res > x) {
02875           res = res - 1.0;
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 /*  not correct e.g. 16.5
03142     _math_setdouble(  0x4337fffffffffffe, nummag   );
03143 
03144     tmpx = x;           
03145     res = (tmpx+nummag) - nummag; 
03146 */
03147 
03148 /*  old version */
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     //  -- rtc version --
03312     //  
03313     //      _math_setdouble(  0x4330000000000000, nummag   );
03314     //  
03315     //      tmpx = x;
03316     //      where (x<0.0) {
03317     //            tmpx = -x;
03318     //      }
03319     //      res = (((tmpx+0.5)+nummag) - nummag)-1.0; 
03320     //      delta = tmpx - res;
03321     //      where (delta >= 1.0) {
03322     //            res = res + 1.0;
03323     //      }
03324     //      where (x<0.0) {
03325     //            res = -res;
03326     //      } 
03327 
03328 
03329     // --  C version --
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      // tmp=unshifted exponent
03339      asm("\tiand.L %0 %1 %2" : "=r" (tmp) : "r" (_emask) , "r" (xr) );
03340      // ie=shifted exponent
03341      asm("\tilsh.L %0 %1 %2" : "=r" (ie) : "r" (tmp) , "r" (_sh) );
03342      // integer exponent
03343      ie = ie - 0x3ff;
03344 
03345      // return 0 for -1 < x < 1
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                                   // write_int(ix);
03409                                   // write_int(iy);
03410   _x.zint &= ~_smask;             // everything except sign of x
03411   _y.zint &= _smask;              // get sign of y
03412                                   // write_int(ix);
03413                                   // write_int(iy);
03414   _x.zint |= _y.zint;             // sign of y into sign of x
03415                                   // write_int(ix);
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 /* old version: not always correct
03509    res = fabs(y)-fabs(fmod(x,y));
03510    res = copysign(res,x);
03511    res = -res;
03512 */
03513    two = 1.0 + 1.0;
03514    ratio = x/y;
03515    n = round(ratio);
03516    two_c = fmod(n,two);
03517 //   write_double(n);
03518    where ( fabs(n-ratio) == 0.5 ) {
03519       n = n - two_c;
03520    }
03521 //   write_double(n);
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                                     //  write_int(ix);
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 // write_int(z.zint);     // one more digit in write_double useful
03691 
03692   return res;
03693 }    
03694 #endif
03695 #endif // Has Main
03696 
03724 /* -------------------------------------------------------------------*/
03725 /* math_inline double nexttoward(double x, long double y) */
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 //  two = 2.0;
03775 
03776 /* old version */
03777 /*
03778   where (x<0.0) {
03779         tmp_i = y;
03780         tmp_y = tmp_i;
03781         where (tmp_y==y) {
03782               tmp_x = -x;
03783               res = exp(y*log(tmp_x));
03784               sign = 1.0-2.0*fmod(y,two); 
03785               res = sign*res;
03786         } else {
03787         tmp_x = log(x);    // crash
03788         }
03789   } 
03790   where (x>0.0) {
03791         res =  exp( y * log(x) );
03792   }
03793 */
03794 
03795 /* new version */
03796   sign = 1.0;
03797   tmp_x = x;
03798   tmp_y = y;
03799   where (tmp_x < 0.0) {
03800      tmp_x = -tmp_x;
03801 /* version 1
03802      tmp_i = y;       //better to use trunc or round
03803      tmp_y = tmp_i;   // danger for large y
03804 */
03805 /*   tmp_y = trunc(y); trunc introduced */
03806 /*
03807        sign = sign - two*fmod(fabs(y),two);
03808        where (tmp_y != y) {
03809         sign = 0x7ff0100000000000ULL;
03810      } 
03811 */
03812 
03813 /* version 2 */
03814      _emask=0x7FF0000000000000ULL;
03815      _sh  =52;
03816 
03817      // compute tmp=trunc(y/2)*2
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      // check for evenness of tmp
03831      tmp = tmp_y - tmp;
03832      where (tmp != 0.0) {
03833         // y not even
03834         res = ((union { unsigned u; double d; }){.u=0x7ff0100000000000ULL}).d; // (NAN)  
03835         where ( (tmp == 1.0) || (tmp == -1.0) )
03836         {  // y odd
03837            sign = -1.0;
03838         }
03839         else
03840            tmp_x = 0.0;
03841      }
03842   }
03843 /*   asm("rtm 0x1000 [ %0 %1 %2 %3 ]" : : "r" (sign), "r" (tmp), "r" (tmp_x), "r" (res) ); -- LM ????????????????? */
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  /* _MATH_H_ */

Generated on Tue Jan 10 12:43:39 2006 for nlibc by doxygen 1.3.5