Ejemplo n.º 1
0
        double nextafter(double x, double y)
{
        int     hx,hy,ix,iy;
        unsigned lx,ly;

        hx = CYG_LIBM_HI(x);            /* high word of x */
        lx = CYG_LIBM_LO(x);            /* low  word of x */
        hy = CYG_LIBM_HI(y);            /* high word of y */
        ly = CYG_LIBM_LO(y);            /* low  word of y */
        ix = hx&0x7fffffff;             /* |x| */
        iy = hy&0x7fffffff;             /* |y| */

        if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */ 
           ((iy>=0x7ff00000)&&((iy-0x7ff00000)|ly)!=0))     /* y is nan */ 
           return x+y;                          
        if(x==y) return x;              /* x=y, return x */
        if((ix|lx)==0) {                        /* x == 0 */
            CYG_LIBM_HI(x) = hy&0x80000000;     /* return +-minsubnormal */
            CYG_LIBM_LO(x) = 1;
            y = x*x;
            if(y==x) return y; else return x;   /* raise underflow flag */
        } 
        if(hx>=0) {                             /* x > 0 */
            if(hx>hy||((hx==hy)&&(lx>ly))) {    /* x > y, x -= ulp */
                if(lx==0) hx -= 1;
                lx -= 1;
            } else {                            /* x < y, x += ulp */
                lx += 1;
                if(lx==0) hx += 1;
            }
        } else {                                /* x < 0 */
            if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
                if(lx==0) hx -= 1;
                lx -= 1;
            } else {                            /* x > y, x += ulp */
                lx += 1;
                if(lx==0) hx += 1;
            }
        }
        hy = hx&0x7ff00000;
        if(hy>=0x7ff00000) return x+x;  /* overflow  */
        if(hy<0x00100000) {             /* underflow */
            y = x*x;
            if(y!=x) {          /* raise underflow flag */
                CYG_LIBM_HI(y) = hx; CYG_LIBM_LO(y) = lx;
                return y;
            }
        }
        CYG_LIBM_HI(x) = hx; CYG_LIBM_LO(x) = lx;
        return x;
}
Ejemplo n.º 2
0
        double __ieee754_log10(double x)
{
        double y,z;
        int i,k,hx;
        unsigned lx;

        hx = CYG_LIBM_HI(x);    /* high word of x */
        lx = CYG_LIBM_LO(x);    /* low word of x */

        k=0;
        if (hx < 0x00100000) {                  /* x < 2**-1022  */
            if (((hx&0x7fffffff)|lx)==0)
                return -two54/zero;             /* log(+-0)=-inf */
            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
            k -= 54; x *= two54; /* subnormal number, scale up x */
            hx = CYG_LIBM_HI(x);                /* high word of x */
        }
        if (hx >= 0x7ff00000) return x+x;
        k += (hx>>20)-1023;
        i  = ((unsigned)k&0x80000000)>>31;
        hx = (hx&0x000fffff)|((0x3ff-i)<<20);
        y  = (double)(k+i);
        CYG_LIBM_HI(x) = hx;
        z  = y*log10_2lo + ivln10*__ieee754_log(x);
        return  z+y*log10_2hi;
}
Ejemplo n.º 3
0
        double __kernel_tan(double x, double y, int iy)
{
        double z,r,v,w,s;
        int ix,hx;
        hx = CYG_LIBM_HI(x);    /* high word of x */
        ix = hx&0x7fffffff;     /* high word of |x| */
        if(ix<0x3e300000)                       /* x < 2**-28 */
            {if((int)x==0) {                    /* generate inexact */
                if(((ix|CYG_LIBM_LO(x))|(iy+1))==0) return one/fabs(x);
                else return (iy==1)? x: -one/x;
            }
            }
        if(ix>=0x3FE59428) {                    /* |x|>=0.6744 */
            if(hx<0) {x = -x; y = -y;}
            z = pio4-x;
            w = pio4lo-y;
            x = z+w; y = 0.0;
        }
        z       =  x*x;
        w       =  z*z;
    /* Break x^5*(T[1]+x^2*T[2]+...) into
     *    x^5(T[1]+x^4*T[3]+...+x^20*T[11]) +
     *    x^5(x^2*(T[2]+x^4*T[4]+...+x^22*[T12]))
     */
        r = T[1]+w*(T[3]+w*(T[5]+w*(T[7]+w*(T[9]+w*T[11]))));
        v = z*(T[2]+w*(T[4]+w*(T[6]+w*(T[8]+w*(T[10]+w*T[12])))));
        s = z*x;
        r = y + z*(s*(r+v)+y);
        r += T[0]*s;
        w = x+r;
        if(ix>=0x3FE59428) {
            v = (double)iy;
            return (double)(1-((hx>>30)&2))*(v-2.0*(x-(w*w/(w+v)-r)));
        }
Ejemplo n.º 4
0
        double __ieee754_log(double x)
{
        double hfsq,f,s,z,R,w,t1,t2,dk;
        int k,hx,i,j;
        unsigned lx;

        hx = CYG_LIBM_HI(x);            /* high word of x */
        lx = CYG_LIBM_LO(x);            /* low  word of x */

        k=0;
        if (hx < 0x00100000) {                  /* x < 2**-1022  */
            if (((hx&0x7fffffff)|lx)==0) 
                return -two54/zero;             /* log(+-0)=-inf */
            if (hx<0) return (x-x)/zero;        /* log(-#) = NaN */
            k -= 54; x *= two54; /* subnormal number, scale up x */
            hx = CYG_LIBM_HI(x);                /* high word of x */
        } 
        if (hx >= 0x7ff00000) return x+x;
        k += (hx>>20)-1023;
        hx &= 0x000fffff;
        i = (hx+0x95f64)&0x100000;
        CYG_LIBM_HI(x) = hx|(i^0x3ff00000);     /* normalize x or x/2 */
        k += (i>>20);
        f = x-1.0;
        if((0x000fffff&(2+hx))<3) {     /* |f| < 2**-20 */
            if(f==zero) {
                if(k==0) return zero;  
                else {
                    dk=(double)k;
                    return dk*ln2_hi+dk*ln2_lo;
                }
            }
            R = f*f*(0.5-0.33333333333333333*f);
            if(k==0) return f-R;
            else {
                dk=(double)k;
                return dk*ln2_hi-((R-dk*ln2_lo)-f);
            }
        }
        s = f/(2.0+f); 
        dk = (double)k;
        z = s*s;
        i = hx-0x6147a;
        w = z*z;
        j = 0x6b851-hx;
        t1= w*(Lg2+w*(Lg4+w*Lg6)); 
        t2= z*(Lg1+w*(Lg3+w*(Lg5+w*Lg7))); 
        i |= j;
        R = t2+t1;
        if(i>0) {
            hfsq=0.5*f*f;
            if(k==0) return f-(hfsq-s*(hfsq+R)); else
                     return dk*ln2_hi-((hfsq-(s*(hfsq+R)+dk*ln2_lo))-f);
        } else {
            if(k==0) return f-s*(f-R); else
                     return dk*ln2_hi-((s*(f-R)-dk*ln2_lo)-f);
        }
}
Ejemplo n.º 5
0
        int isnan(double x)
{
        int hx,lx;
        hx = (CYG_LIBM_HI(x)&0x7fffffff);
        lx = CYG_LIBM_LO(x);
        hx |= (unsigned)(lx|(-lx))>>31; 
        hx = 0x7ff00000 - hx;
        return ((unsigned)(hx))>>31;
}
Ejemplo n.º 6
0
        double cbrt(double x) 
{
        int     hx;
        double r,s,t=0.0,w;
        unsigned sign;


        hx = CYG_LIBM_HI(x);            /* high word of x */
        sign=hx&0x80000000;             /* sign= sign(x) */
        hx  ^=sign;
        if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
        if((hx|CYG_LIBM_LO(x))==0) 
            return(x);          /* cbrt(0) is itself */

        CYG_LIBM_HI(x) = hx;    /* x <- |x| */
    /* rough cbrt to 5 bits */
        if(hx<0x00100000)               /* subnormal number */
          {CYG_LIBM_HI(t)=0x43500000;           /* set t= 2**54 */
           t*=x; CYG_LIBM_HI(t)=CYG_LIBM_HI(t)/3+B2;
          }
        else
          CYG_LIBM_HI(t)=hx/3+B1;       


    /* new cbrt to 23 bits, may be implemented in single precision */
        r=t*t/x;
        s=C+r*t;
        t*=G+F/(s+E+D/s);       

    /* chopped to 20 bits and make it larger than cbrt(x) */ 
        CYG_LIBM_LO(t)=0; CYG_LIBM_HI(t)+=0x00000001;


    /* one step newton iteration to 53 bits with error less than 0.667 ulps */
        s=t*t;          /* t*t is exact */
        r=x/s;
        w=t+t;
        r=(r-t)/(w+r);  /* r-s is exact */
        t=t+t*r;

    /* retore the sign bit */
        CYG_LIBM_HI(t) |= sign;
        return(t);
}
Ejemplo n.º 7
0
        double __ieee754_asin(double x)
{
        double t,w,p,q,c,r,s;
        int hx,ix;
        
        hx = CYG_LIBM_HI(x);
        ix = hx&0x7fffffff;
        if(ix>= 0x3ff00000) {           /* |x|>= 1 */
            if(((ix-0x3ff00000)|CYG_LIBM_LO(x))==0)
                    /* asin(1)=+-pi/2 with inexact */
                return x*pio2_hi+x*pio2_lo;     
            return (x-x)/(x-x);         /* asin(|x|>1) is NaN */   
        } else if (ix<0x3fe00000) {     /* |x|<0.5 */
            if(ix<0x3e400000) {         /* if |x| < 2**-27 */
                if(huge+x>one) return x;/* return x with inexact if x!=0*/
            } else {
                t = x*x;
                p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
                q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
                w = p/q;
                return x+x*w;
            }
        }
        /* 1> |x|>= 0.5 */
        w = one-fabs(x);
        t = w*0.5;
        p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
        q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
        s = sqrt(t);
        if(ix>=0x3FEF3333) {    /* if |x| > 0.975 */
            w = p/q;
            t = pio2_hi-(2.0*(s+s*w)-pio2_lo);
        } else {
            w  = s;
            CYG_LIBM_LO(w) = 0;
            c  = (t-w*w)/(s+w);
            r  = p/q;
            p  = 2.0*s*r-(pio2_lo-2.0*c);
            q  = pio4_hi-2.0*w;
            t  = pio4_hi-(p-q);
        }    
        if(hx>0) return t; else return -t;    
}
Ejemplo n.º 8
0
        double logb(double x)
{
        int lx,ix;
        ix = (CYG_LIBM_HI(x))&0x7fffffff;       /* high |x| */
        lx = CYG_LIBM_LO(x);                    /* low x */
        if((ix|lx)==0) return -1.0/fabs(x);
        if(ix>=0x7ff00000) return x*x;
        if((ix>>=20)==0)                        /* IEEE 754 logb */
                return -1022.0; 
        else
                return (double) (ix-1023); 
Ejemplo n.º 9
0
        double __ieee754_acos(double x)
{
        double z,p,q,r,w,s,c,df;
        int hx,ix;
        hx = CYG_LIBM_HI(x);
        ix = hx&0x7fffffff;
        if(ix>=0x3ff00000) {    /* |x| >= 1 */
            if(((ix-0x3ff00000)|CYG_LIBM_LO(x))==0) {   /* |x|==1 */
                if(hx>0) return 0.0;            /* acos(1) = 0  */
                else return pi+2.0*pio2_lo;     /* acos(-1)= pi */
            }
            return (x-x)/(x-x);         /* acos(|x|>1) is NaN */
        }
        if(ix<0x3fe00000) {     /* |x| < 0.5 */
            if(ix<=0x3c600000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/
            z = x*x;
            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
            r = p/q;
            return pio2_hi - (x - (pio2_lo-x*r));
        } else  if (hx<0) {             /* x < -0.5 */
            z = (one+x)*0.5;
            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
            s = sqrt(z);
            r = p/q;
            w = r*s-pio2_lo;
            return pi - 2.0*(s+w);
        } else {                        /* x > 0.5 */
            z = (one-x)*0.5;
            s = sqrt(z);
            df = s;
            CYG_LIBM_LO(df) = 0;
            c  = (z-df*df)/(s+df);
            p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5)))));
            q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4)));
            r = p/q;
            w = r*s+c;
            return 2.0*(df+w);
        }
}
Ejemplo n.º 10
0
        double __ieee754_y0(double x) 
{
        double z, s,c,ss,cc,u,v;
        int hx,ix,lx;

        hx = CYG_LIBM_HI(x);
        ix = 0x7fffffff&hx;
        lx = CYG_LIBM_LO(x);
    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0  */
        if(ix>=0x7ff00000) return  one/(x+x*x); 
        if((ix|lx)==0) return -one/zero;
        if(hx<0) return zero/zero;
        if(ix >= 0x40000000) {  /* |x| >= 2.0 */
        /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
         * where x0 = x-pi/4
         *      Better formula:
         *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
         *                      =  1/sqrt(2) * (sin(x) + cos(x))
         *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
         *                      =  1/sqrt(2) * (sin(x) - cos(x))
         * To avoid cancellation, use
         *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
         * to compute the worse one.
         */
                s = sin(x);
                c = cos(x);
                ss = s-c;
                cc = s+c;
        /*
         * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
         * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
         */
                if(ix<0x7fe00000) {  /* make sure x+x not overflow */
                    z = -cos(x+x);
                    if ((s*c)<zero) cc = z/ss;
                    else            ss = z/cc;
                }
                if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x);
                else {
                    u = pzero(x); v = qzero(x);
                    z = invsqrtpi*(u*ss+v*cc)/sqrt(x);
                }
                return z;
        }
        if(ix<=0x3e400000) {    /* x < 2**-27 */
            return(u00 + tpi*__ieee754_log(x));
        }
        z = x*x;
        u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
        v = one+z*(v01+z*(v02+z*(v03+z*v04)));
        return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x)));
}
Ejemplo n.º 11
0
        double frexp(double x, int *eptr)
{
        int  hx, ix, lx;
        hx = CYG_LIBM_HI(x);
        ix = 0x7fffffff&hx;
        lx = CYG_LIBM_LO(x);
        *eptr = 0;
        if(ix>=0x7ff00000||((ix|lx)==0)) return x;      /* 0,inf,nan */
        if (ix<0x00100000) {            /* subnormal */
            x *= two54;
            hx = CYG_LIBM_HI(x);
            ix = hx&0x7fffffff;
            *eptr = -54;
        }
        *eptr += (ix>>20)-1022;
        hx = (hx&0x800fffff)|0x3fe00000;
        CYG_LIBM_HI(x) = hx;
        return x;
}
Ejemplo n.º 12
0
        double __ieee754_acosh(double x)
{       
        double t;
        int hx;
        hx = CYG_LIBM_HI(x);
        if(hx<0x3ff00000) {             /* x < 1 */
            return (x-x)/(x-x);
        } else if(hx >=0x41b00000) {    /* x > 2**28 */
            if(hx >=0x7ff00000) {       /* x is inf of NaN */
                return x+x;
            } else 
                return __ieee754_log(x)+ln2;    /* acosh(huge)=log(2x) */
        } else if(((hx-0x3ff00000)|CYG_LIBM_LO(x))==0) {
            return 0.0;                 /* acosh(1) = 0 */
        } else if (hx > 0x40000000) {   /* 2**28 > x > 2 */
            t=x*x;
            return __ieee754_log(2.0*x-one/(x+sqrt(t-one)));
        } else {                        /* 1<x<2 */
            t = x-one;
            return log1p(t+sqrt(2.0*t+t*t));
        }
}
Ejemplo n.º 13
0
        double __ieee754_sinh(double x)
{       
        double t,w,h;
        int ix,jx;
        unsigned lx;

    /* High word of |x|. */
        jx = CYG_LIBM_HI(x);
        ix = jx&0x7fffffff;

    /* x is INF or NaN */
        if(ix>=0x7ff00000) return x+x;  

        h = 0.5;
        if (jx<0) h = -h;
    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
        if (ix < 0x40360000) {          /* |x|<22 */
            if (ix<0x3e300000)          /* |x|<2**-28 */
                if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
            t = expm1(fabs(x));
            if(ix<0x3ff00000) return h*(2.0*t-t*t/(t+one));
            return h*(t+t/(t+one));
        }

    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
        if (ix < 0x40862E42)  return h*__ieee754_exp(fabs(x));

    /* |x| in [log(maxdouble), overflowthresold] */
        lx = CYG_LIBM_LO(x);
        if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(unsigned)0x8fb9f87d))) {
            w = __ieee754_exp(0.5*fabs(x));
            t = h*w;
            return t*w;
        }

    /* |x| > overflowthresold, sinh(x) overflow */
        return x*shuge;
}
Ejemplo n.º 14
0
        double __ieee754_hypot(double x, double y)
{
        double a=x,b=y,t1,t2,y1,y2,w;
        int j,k,ha,hb;

        ha = CYG_LIBM_HI(x)&0x7fffffff; /* high word of  x */
        hb = CYG_LIBM_HI(y)&0x7fffffff; /* high word of  y */
        if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
        CYG_LIBM_HI(a) = ha;    /* a <- |a| */
        CYG_LIBM_HI(b) = hb;    /* b <- |b| */
        if((ha-hb)>0x3c00000) {return a+b;} /* x/y > 2**60 */
        k=0;
        if(ha > 0x5f300000) {   /* a>2**500 */
           if(ha >= 0x7ff00000) {       /* Inf or NaN */
               w = a+b;                 /* for sNaN */
               if(((ha&0xfffff)|CYG_LIBM_LO(a))==0) w = a;
               if(((hb^0x7ff00000)|CYG_LIBM_LO(b))==0) w = b;
               return w;
           }
           /* scale a and b by 2**-600 */
           ha -= 0x25800000; hb -= 0x25800000;  k += 600;
           CYG_LIBM_HI(a) = ha;
           CYG_LIBM_HI(b) = hb;
        }
        if(hb < 0x20b00000) {   /* b < 2**-500 */
            if(hb <= 0x000fffff) {      /* subnormal b or 0 */  
                if((hb|(CYG_LIBM_LO(b)))==0) return a;
                t1=0;
                CYG_LIBM_HI(t1) = 0x7fd00000;   /* t1=2^1022 */
                b *= t1;
                a *= t1;
                k -= 1022;
            } else {            /* scale a and b by 2^600 */
                ha += 0x25800000;       /* a *= 2^600 */
                hb += 0x25800000;       /* b *= 2^600 */
                k -= 600;
                CYG_LIBM_HI(a) = ha;
                CYG_LIBM_HI(b) = hb;
            }
        }
    /* medium size a and b */
        w = a-b;
        if (w>b) {
            t1 = 0;
            CYG_LIBM_HI(t1) = ha;
            t2 = a-t1;
            w  = sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
        } else {
            a  = a+a;
            y1 = 0;
            CYG_LIBM_HI(y1) = hb;
            y2 = b - y1;
            t1 = 0;
            CYG_LIBM_HI(t1) = ha+0x00100000;
            t2 = a - t1;
            w  = sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
        }
        if(k!=0) {
            t1 = 1.0;
            CYG_LIBM_HI(t1) += (k<<20);
            return t1*w;
        } else return w;
}