Пример #1
0
double
__ieee754_exp10 (double arg)
{
  int32_t lx;
  double arg_high, arg_low;
  double exp_high, exp_low;

  if (!isfinite (arg))
    return __ieee754_exp (arg);
  if (arg < DBL_MIN_10_EXP - DBL_DIG - 10)
    return DBL_MIN * DBL_MIN;
  else if (arg > DBL_MAX_10_EXP + 1)
    return DBL_MAX * DBL_MAX;
  else if (fabs (arg) < 0x1p-56)
    return 1.0;

  GET_LOW_WORD (lx, arg);
  lx &= 0xf8000000;
  arg_high = arg;
  SET_LOW_WORD (arg_high, lx);
  arg_low = arg - arg_high;
  exp_high = arg_high * log10_high;
  exp_low = arg_high * log10_low + arg_low * M_LN10;
  return __ieee754_exp (exp_high) * __ieee754_exp (exp_low);
}
Пример #2
0
int
__ieee754_ilogb (double x)
{
  int32_t hx, lx, ix;

  GET_HIGH_WORD (hx, x);
  hx &= 0x7fffffff;
  if (hx < 0x00100000)
    {
      GET_LOW_WORD (lx, x);
      if ((hx | lx) == 0)
	return FP_ILOGB0;               /* ilogb(0) = FP_ILOGB0 */
      else                              /* subnormal x */
      if (hx == 0)
	{
	  for (ix = -1043; lx > 0; lx <<= 1)
	    ix -= 1;
	}
      else
	{
	  for (ix = -1022, hx <<= 11; hx > 0; hx <<= 1)
	    ix -= 1;
	}
      return ix;
    }
  else if (hx < 0x7ff00000)
    return (hx >> 20) - 1023;
  else if (FP_ILOGBNAN != INT_MAX)
Пример #3
0
double atan(double x)
{
	double w,s1,s2,z;
	int32_t ix,hx,id;

	GET_HIGH_WORD(hx, x);
	ix = hx & 0x7fffffff;
	if (ix >= 0x44100000) {   /* if |x| >= 2^66 */
		uint32_t low;

		GET_LOW_WORD(low, x);
		if (ix > 0x7ff00000 ||
		    (ix == 0x7ff00000 && low != 0))  /* NaN */
			return x+x;
		if (hx > 0)
			return  atanhi[3] + *(volatile double *)&atanlo[3];
		else
			return -atanhi[3] - *(volatile double *)&atanlo[3];
	}
	if (ix < 0x3fdc0000) {    /* |x| < 0.4375 */
		if (ix < 0x3e400000) {  /* |x| < 2^-27 */
			/* raise inexact */
			if (huge+x > 1.0)
				return x;
		}
		id = -1;
	} else {
		x = fabs(x);
		if (ix < 0x3ff30000) {  /* |x| < 1.1875 */
			if (ix < 0x3fe60000) {  /*  7/16 <= |x| < 11/16 */
				id = 0;
				x = (2.0*x-1.0)/(2.0+x);
			} else {                /* 11/16 <= |x| < 19/16 */
				id = 1;
				x = (x-1.0)/(x+1.0);
			}
		} else {
			if (ix < 0x40038000) {  /* |x| < 2.4375 */
				id = 2;
				x = (x-1.5)/(1.0+1.5*x);
			} else {                /* 2.4375 <= |x| < 2^66 */
				id = 3;
				x = -1.0/x;
			}
		}
	}
	/* end of argument reduction */
	z = x*x;
	w = z*z;
	/* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */
	s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10])))));
	s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9]))));
	if (id < 0)
		return x - x*(s1+s2);
	z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
	return hx < 0 ? -z : z;
}
Пример #4
0
double acos(double x)
{
	double z, p, q, r, w, s, c, df;
	s32_t hx, ix;

	GET_HIGH_WORD(hx,x);
	ix = hx & 0x7fffffff;
	if (ix >= 0x3ff00000)
	{
		u32_t lx;
		GET_LOW_WORD(lx,x);
		if (((ix - 0x3ff00000) | lx) == 0)
		{
			if (hx > 0)
				return 0.0;
			else
				return pi + 2.0 * pio2_lo;
		}
		return (x - x) / (x - x);
	}
	if (ix < 0x3fe00000)
	{
		if (ix <= 0x3c600000)
			return pio2_hi + pio2_lo;
		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)
	{
		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
	{
		z = (one - x) * 0.5;
		s = sqrt(z);
		df = s;
		SET_LOW_WORD(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);
	}
}
Пример #5
0
double
__ieee754_cosh (double x)
{
  double t, w;
  int32_t ix;
  u_int32_t lx;

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

  /* |x| in [0,22] */
  if (ix < 0x40360000)
    {
      /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
      if (ix < 0x3fd62e43)
	{
	  if (ix < 0x3c800000)
	    return one;                                   /* cosh(tiny) = 1 */
	  t = __expm1 (fabs (x));
	  w = one + t;
	  return one + (t * t) / (w + w);
	}

      /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
      t = __ieee754_exp (fabs (x));
      return half * t + half / t;
    }

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

  /* |x| in [log(maxdouble), overflowthresold] */
  GET_LOW_WORD (lx, x);
  if (ix < 0x408633ce || ((ix == 0x408633ce) && (lx <= (u_int32_t) 0x8fb9f87d)))
    {
      w = __ieee754_exp (half * fabs (x));
      t = half * w;
      return t * w;
    }

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

  /* |x| > overflowthresold, cosh(x) overflow */
  return huge * huge;
}
Пример #6
0
double
cbrt(double x) 
{
	int32_t	hx;
	double r,s,t=0.0,w;
	u_int32_t sign;
	u_int32_t high,low;

	GET_HIGH_WORD(hx,x);
	sign=hx&0x80000000; 		/* sign= sign(x) */
	hx  ^=sign;
	if(hx>=0x7ff00000) return(x+x); /* cbrt(NaN,INF) is itself */
	GET_LOW_WORD(low,x);
	if((hx|low)==0) 
	    return(x);		/* cbrt(0) is itself */

	SET_HIGH_WORD(x,hx);	/* x <- |x| */
    /* rough cbrt to 5 bits */
	if(hx<0x00100000) 		/* subnormal number */
	  {SET_HIGH_WORD(t,0x43500000);	/* set t= 2**54 */
	   t*=x; GET_HIGH_WORD(high,t); SET_HIGH_WORD(t,high/3+B2);
	  }
	else
	  SET_HIGH_WORD(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) */ 
	GET_HIGH_WORD(high,t);
	INSERT_WORDS(t,high+0x00000001,0);


    /* 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 */
	GET_HIGH_WORD(high,t);
	SET_HIGH_WORD(t,high|sign);
	return(t);
}
Пример #7
0
double asin(double x)
{
	double t=0.0,w,p,q,c,r,s;
	int32_t hx,ix;

	GET_HIGH_WORD(hx, x);
	ix = hx & 0x7fffffff;
	if (ix >= 0x3ff00000) {           /* |x|>= 1 */
		uint32_t lx;

		GET_LOW_WORD(lx, x);
		if ((ix-0x3ff00000 | lx) == 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 < 0x3e500000) {  /* if |x| < 2**-26 */
			if (huge+x > 1.0)
				return x; /* return x with inexact if x!=0*/
		}
		t = x*x;
		p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
		q = 1.0+t*(qS1+t*(qS2+t*(qS3+t*qS4)));
		w = p/q;
		return x + x*w;
	}
	/* 1 > |x| >= 0.5 */
	w = 1.0 - fabs(x);
	t = w*0.5;
	p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5)))));
	q = 1.0+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;
		SET_LOW_WORD(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;
	return -t;
}
Пример #8
0
static double sin_pi(double x)
{
	double y,z;
	int n,ix;

	GET_HIGH_WORD(ix, x);
	ix &= 0x7fffffff;

	if (ix < 0x3fd00000)
		return __sin(pi*x, 0.0, 0);

	y = -x;  /* negative x is assumed */

	/*
	 * argument reduction, make sure inexact flag not raised if input
	 * is an integer
	 */
	z = floor(y);
	if (z != y) {    /* inexact anyway */
		y *= 0.5;
		y  = 2.0*(y - floor(y));   /* y = |x| mod 2.0 */
		n  = (int)(y*4.0);
	} else {
		if (ix >= 0x43400000) {
			y = 0.0;    /* y must be even */
			n = 0;
		} else {
			if (ix < 0x43300000)
				z = y + two52;  /* exact */
			GET_LOW_WORD(n, z);
			n &= 1;
			y = n;
			n <<= 2;
		}
	}
	switch (n) {
	case 0:  y =  __sin(pi*y, 0.0, 0); break;
	case 1:
	case 2:  y =  __cos(pi*(0.5-y), 0.0); break;
	case 3:
	case 4:  y =  __sin(pi*(1.0-y), 0.0, 0); break;
	case 5:
	case 6:  y = -__cos(pi*(y-1.5), 0.0); break;
	default: y =  __sin(pi*(y-2.0), 0.0, 0); break;
	}
	return -y;
}
Пример #9
0
double
expm1(double x)
{
	double y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
	int32_t k,xsb;
	uint32_t hx;

	GET_HIGH_WORD(hx,x);
	xsb = hx&0x80000000;		/* sign bit of x */
	hx &= 0x7fffffff;		/* high word of |x| */

    /* filter out huge and non-finite argument */
	if(hx >= 0x4043687A) {			/* if |x|>=56*ln2 */
	    if(hx >= 0x40862E42) {		/* if |x|>=709.78... */
                if(hx>=0x7ff00000) {
		    uint32_t low;
		    GET_LOW_WORD(low,x);
		    if(((hx&0xfffff)|low)!=0)
		         return x+x; 	 /* NaN */
		    else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
	        }
	        if(x > o_threshold) return huge*huge; /* overflow */
	    }
	    if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
		if(x+tiny<0.0)		/* raise inexact */
		return tiny-one;	/* return -1 */
	    }
	}

    /* argument reduction */
	if(hx > 0x3fd62e42) {		/* if  |x| > 0.5 ln2 */
	    if(hx < 0x3FF0A2B2) {	/* and |x| < 1.5 ln2 */
		if(xsb==0)
		    {hi = x - ln2_hi; lo =  ln2_lo;  k =  1;}
		else
		    {hi = x + ln2_hi; lo = -ln2_lo;  k = -1;}
	    } else {
		k  = invln2*x+((xsb==0)?0.5:-0.5);
		t  = k;
		hi = x - t*ln2_hi;	/* t*ln2_hi is exact here */
		lo = t*ln2_lo;
	    }
	    STRICT_ASSIGN(double, x, hi - lo);
	    c  = (hi-x)-lo;
	}
	else if(hx < 0x3c900000) {  	/* when |x|<2**-54, return x */
Пример #10
0
double
__ieee754_acos(double x)
{
	double z, p, q, r, w, s, c, df;
	int32_t hx, ix;
	GET_HIGH_WORD(hx, x);
	ix = hx & 0x7fffffff;
	if (ix >= 0x3ff00000) {	/* |x| >= 1 */
		uint32_t lx;
		GET_LOW_WORD(lx, x);
		if (((ix - 0x3ff00000) | lx) == 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;
		SET_LOW_WORD(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);
	}
}
Пример #11
0
int ilogb(double x)
{
	int32_t hx,lx,ix;

	GET_HIGH_WORD(hx,x);
	hx &= 0x7fffffff;
	if(hx<0x00100000) {
	    GET_LOW_WORD(lx,x);
	    if((hx|lx)==0)
		return 0x80000001;	/* ilogb(0) = 0x80000001 */
	    else			/* subnormal x */
		if(hx==0) {
		    for (ix = -1043; lx>0; lx<<=1) ix -=1;
		} else {
		    for (ix = -1022,hx<<=11; hx>0; hx<<=1) ix -=1;
		}
	    return ix;
	}
	else if (hx<0x7ff00000) return (hx>>20)-1023;
	else return 0x7fffffff;
double cosh(double x)
{
	double t, w;
	s32_t ix;
	u32_t lx;

	GET_HIGH_WORD(ix,x);
	ix &= 0x7fffffff;

	if (ix >= 0x7ff00000)
		return x * x;

	if (ix < 0x3fd62e43)
	{
		t = expm1(fabs(x));
		w = one + t;
		if (ix < 0x3c800000)
			return w;
		return one + (t * t) / (w + w);
	}

	if (ix < 0x40360000)
	{
		t = exp(fabs(x));
		return half * t + half / t;
	}

	if (ix < 0x40862E42)
		return half * exp(fabs(x));

	GET_LOW_WORD(lx,x);
	if (ix < 0x408633CE || ((ix == 0x408633ce)
			&& (lx <= (u32_t) 0x8fb9f87d)))
	{
		w = exp(half * fabs(x));
		t = half * w;
		return t * w;
	}

	return huge * huge;
}
Пример #13
0
double
__ieee754_sinh(double x)
{
	double t,w,h;
	int32_t ix,jx;
	uint32_t lx;

    /* High word of |x|. */
	GET_HIGH_WORD(jx,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] */
	GET_LOW_WORD(lx,x);
	if (ix<0x408633CE || ((ix==0x408633ce)&&(lx<=(uint32_t)0x8fb9f87d))) {
	    w = __ieee754_exp(0.5*fabs(x));
	    t = h*w;
	    return t*w;
	}

    /* |x| > overflowthresold, sinh(x) overflow */
	return x*shuge;
}
Пример #14
0
	double __kernel_tan(double x, double y, int iy)
{
	double z,r,v,w,s;
	int32_t ix,hx;
	GET_HIGH_WORD(hx,x);
	ix = hx&0x7fffffff;	/* high word of |x| */
	if(ix<0x3e300000)			/* x < 2**-28 */
	    {if((int)x==0) {			/* generate inexact */
		u_int32_t low;
		GET_LOW_WORD(low,x);
		if(((ix|low)|(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)));
	}
Пример #15
0
Файл: exp2.c Проект: 5kg/osv
/*
 * exp2(x): compute the base 2 exponential of x
 *
 * Accuracy: Peak error < 0.503 ulp for normalized results.
 *
 * Method: (accurate tables)
 *
 *   Reduce x:
 *     x = 2**k + y, for integer k and |y| <= 1/2.
 *     Thus we have exp2(x) = 2**k * exp2(y).
 *
 *   Reduce y:
 *     y = i/TBLSIZE + z - eps[i] for integer i near y * TBLSIZE.
 *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z - eps[i]),
 *     with |z - eps[i]| <= 2**-9 + 2**-39 for the table used.
 *
 *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z - eps[i]) via
 *   a degree-5 minimax polynomial with maximum error under 1.3 * 2**-61.
 *   The values in exp2t[] and eps[] are chosen such that
 *   exp2t[i] = exp2(i/TBLSIZE + eps[i]), and eps[i] is a small offset such
 *   that exp2t[i] is accurate to 2**-64.
 *
 *   Note that the range of i is +-TBLSIZE/2, so we actually index the tables
 *   by i0 = i + TBLSIZE/2.  For cache efficiency, exp2t[] and eps[] are
 *   virtual tables, interleaved in the real table tbl[].
 *
 *   This method is due to Gal, with many details due to Gal and Bachelis:
 *
 *      Gal, S. and Bachelis, B.  An Accurate Elementary Mathematical Library
 *      for the IEEE Floating Point Standard.  TOMS 17(1), 26-46 (1991).
 */
double exp2(double x)
{
	double r, t, z;
	uint32_t hx, ix, i0;
	union {uint32_t u; int32_t i;} k;

	/* Filter out exceptional cases. */
	GET_HIGH_WORD(hx, x);
	ix = hx & 0x7fffffff;
	if (ix >= 0x40900000) {        /* |x| >= 1024 */
		if (ix >= 0x7ff00000) {
			GET_LOW_WORD(ix, x);
			if (hx == 0xfff00000 && ix == 0) /* -inf */
				return 0;
			return x;
		}
		if (x >= 1024) {
			STRICT_ASSIGN(double, x, x * 0x1p1023);
			return x;
		}
		if (x <= -1075) {
			STRICT_ASSIGN(double, x, 0x1p-1000*0x1p-1000);
			return x;
		}
Пример #16
0
double
__ieee754_hypot(double x, double y)
{
	double a, b, t1, t2, y1, y2, w;
	int32_t j, k, ha, hb;

	GET_HIGH_WORD(ha, x);
	ha &= 0x7fffffff;
	GET_HIGH_WORD(hb, y);
	hb &= 0x7fffffff;
	if (hb > ha) { a = y; b = x; j = ha; ha = hb; hb = j; }
	else { a = x; b = y; }
	a = fabs(a);
	b = fabs(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 */
			uint32_t low;
			/* Use original arg order iff result is NaN; quieten sNaNs. */
			w = fabs(x + 0.0) - fabs(y + 0.0);
			GET_LOW_WORD(low, a);
			if (((ha & 0xfffff) | low) == 0) w = a;
			GET_LOW_WORD(low, b);
			if (((hb ^ 0x7ff00000) | low) == 0) w = b;
			return w;
		}
		/* scale a and b by 2**-600 */
		ha -= 0x25800000; hb -= 0x25800000;	k += 600;
		SET_HIGH_WORD(a, ha);
		SET_HIGH_WORD(b, hb);
	}
	if (hb < 0x20b00000) {	/* b < 2**-500 */
		if (hb <= 0x000fffff) {	/* subnormal b or 0 */
			uint32_t low;
			GET_LOW_WORD(low, b);
			if ((hb | low) == 0) return a;
			t1 = 0;
			SET_HIGH_WORD(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;
			SET_HIGH_WORD(a, ha);
			SET_HIGH_WORD(b, hb);
		}
	}
	/* medium size a and b */
	w = a - b;
	if (w>b) {
		t1 = 0;
		SET_HIGH_WORD(t1, ha);
		t2 = a - t1;
		w = sqrt(t1*t1 - (b*(-b) - t2*(a + t1)));
	}
	else {
		a = a + a;
		y1 = 0;
		SET_HIGH_WORD(y1, hb);
		y2 = b - y1;
		t1 = 0;
		SET_HIGH_WORD(t1, ha + 0x00100000);
		t2 = a - t1;
		w = sqrt(t1*y1 - (w*(-w) - (t1*y2 + t2*b)));
	}
	if (k != 0) {
		uint32_t high;
		t1 = 1.0;
		GET_HIGH_WORD(high, t1);
		SET_HIGH_WORD(t1, high + (k << 20));
		return t1*w;
	}
	else return w;
}
Пример #17
0
double
expm1(double x)
{
	double y,hi,lo,c,t,e,hxs,hfx,r1;
	int32_t k,xsb;
	uint32_t hx;

	c = 0;
	GET_HIGH_WORD(hx,x);
	xsb = hx&0x80000000;		/* sign bit of x */
	if(xsb==0) y=x; else y= -x;	/* y = |x| */
	hx &= 0x7fffffff;		/* high word of |x| */

    /* filter out huge and non-finite argument */
	if(hx >= 0x4043687A) {			/* if |x|>=56*ln2 */
	    if(hx >= 0x40862E42) {		/* if |x|>=709.78... */
                if(hx>=0x7ff00000) {
		    uint32_t low;
		    GET_LOW_WORD(low,x);
		    if(((hx&0xfffff)|low)!=0)
		         return x+x; 	 /* NaN */
		    else return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
	        }
	        if(x > o_threshold) return huge*huge; /* overflow */
	    }
	    if(xsb!=0) { /* x < -56*ln2, return -1.0 with inexact */
		if(x+tiny<0.0)		/* raise inexact */
		return tiny-one;	/* return -1 */
	    }
	}

    /* argument reduction */
	if(hx > 0x3fd62e42) {		/* if  |x| > 0.5 ln2 */
	    if(hx < 0x3FF0A2B2) {	/* and |x| < 1.5 ln2 */
		if(xsb==0)
		    {hi = x - ln2_hi; lo =  ln2_lo;  k =  1;}
		else
		    {hi = x + ln2_hi; lo = -ln2_lo;  k = -1;}
	    } else {
		k  = invln2*x+((xsb==0)?0.5:-0.5);
		t  = k;
		hi = x - t*ln2_hi;	/* t*ln2_hi is exact here */
		lo = t*ln2_lo;
	    }
	    x  = hi - lo;
	    c  = (hi-x)-lo;
	}
	else if(hx < 0x3c900000) {  	/* when |x|<2**-54, return x */
	    t = huge+x;	/* return x with inexact flags when x!=0 */
	    return x - (t-(huge+x));
	}
	else k = 0;

    /* x is now in primary range */
	hfx = 0.5*x;
	hxs = x*hfx;
	r1 = one+hxs*(Q1+hxs*(Q2+hxs*(Q3+hxs*(Q4+hxs*Q5))));
	t  = 3.0-r1*hfx;
	e  = hxs*((r1-t)/(6.0 - x*t));
	if(k==0) return x - (x*e-hxs);		/* c is 0 */
	else {
	    e  = (x*(e-c)-c);
	    e -= hxs;
	    if(k== -1) return 0.5*(x-e)-0.5;
	    if(k==1)  {
	       	if(x < -0.25) return -2.0*(e-(x+0.5));
	       	else 	      return  one+2.0*(x-e);
	    }
	    if (k <= -2 || k>56) {   /* suffice to return exp(x)-1 */
	        uint32_t high;
	        y = one-(e-x);
		GET_HIGH_WORD(high,y);
		SET_HIGH_WORD(y,high+(k<<20));	/* add k to y's exponent */
	        return y-one;
	    }
	    t = one;
	    if(k<20) {
	        uint32_t high;
	        SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k));  /* t=1-2^-k */
	       	y = t-(e-x);
		GET_HIGH_WORD(high,y);
		SET_HIGH_WORD(y,high+(k<<20));	/* add k to y's exponent */
	   } else {
Пример #18
0
double
__ieee754_hypot (double x, double y)
{
  double a, b, t1, t2, y1, y2, w;
  int32_t j, k, ha, hb;

  GET_HIGH_WORD (ha, x);
  ha &= 0x7fffffff;
  GET_HIGH_WORD (hb, y);
  hb &= 0x7fffffff;
  if (hb > ha)
    {
      a = y; b = x; j = ha; ha = hb; hb = j;
    }
  else
    {
      a = x; b = y;
    }
  SET_HIGH_WORD (a, ha);        /* a <- |a| */
  SET_HIGH_WORD (b, hb);        /* b <- |b| */
  if ((ha - hb) > 0x3c00000)
    {
      return a + b;
    }                                       /* x/y > 2**60 */
  k = 0;
  if (__glibc_unlikely (ha > 0x5f300000))                  /* a>2**500 */
    {
      if (ha >= 0x7ff00000)             /* Inf or NaN */
	{
	  u_int32_t low;
	  w = a + b;                    /* for sNaN */
	  GET_LOW_WORD (low, a);
	  if (((ha & 0xfffff) | low) == 0)
	    w = a;
	  GET_LOW_WORD (low, b);
	  if (((hb ^ 0x7ff00000) | low) == 0)
	    w = b;
	  return w;
	}
      /* scale a and b by 2**-600 */
      ha -= 0x25800000; hb -= 0x25800000;  k += 600;
      SET_HIGH_WORD (a, ha);
      SET_HIGH_WORD (b, hb);
    }
  if (__builtin_expect (hb < 0x23d00000, 0))            /* b < 2**-450 */
    {
      if (hb <= 0x000fffff)             /* subnormal b or 0 */
	{
	  u_int32_t low;
	  GET_LOW_WORD (low, b);
	  if ((hb | low) == 0)
	    return a;
	  t1 = 0;
	  SET_HIGH_WORD (t1, 0x7fd00000);       /* t1=2^1022 */
	  b *= t1;
	  a *= t1;
	  k -= 1022;
	  GET_HIGH_WORD (ha, a);
	  GET_HIGH_WORD (hb, b);
	  if (hb > ha)
	    {
	      t1 = a;
	      a = b;
	      b = t1;
	      j = ha;
	      ha = hb;
	      hb = j;
	    }
	}
      else                      /* scale a and b by 2^600 */
	{
	  ha += 0x25800000;             /* a *= 2^600 */
	  hb += 0x25800000;             /* b *= 2^600 */
	  k -= 600;
	  SET_HIGH_WORD (a, ha);
	  SET_HIGH_WORD (b, hb);
	}
    }
  /* medium size a and b */
  w = a - b;
  if (w > b)
    {
      t1 = 0;
      SET_HIGH_WORD (t1, ha);
      t2 = a - t1;
      w = __ieee754_sqrt (t1 * t1 - (b * (-b) - t2 * (a + t1)));
    }
  else
    {
      a = a + a;
      y1 = 0;
      SET_HIGH_WORD (y1, hb);
      y2 = b - y1;
      t1 = 0;
      SET_HIGH_WORD (t1, ha + 0x00100000);
      t2 = a - t1;
      w = __ieee754_sqrt (t1 * y1 - (w * (-w) - (t1 * y2 + t2 * b)));
    }
  if (k != 0)
    {
      u_int32_t high;
      t1 = 1.0;
      GET_HIGH_WORD (high, t1);
      SET_HIGH_WORD (t1, high + (k << 20));
      w *= t1;
      math_check_force_underflow_nonneg (w);
      return w;
    }
  else
    return w;
}
Пример #19
0
double expm1(double x)
{
	double y, hi, lo, c=0, t, e, hxs, hfx, r1;
	s32_t k, xsb;
	u32_t hx;

	GET_HIGH_WORD(hx,x);
	xsb = hx & 0x80000000;
	if (xsb == 0)
		y = x;
	else
		y = -x;
	hx &= 0x7fffffff;

	if (hx >= 0x4043687A)
	{
		if (hx >= 0x40862E42)
		{
			if (hx >= 0x7ff00000)
			{
				u32_t low;
				GET_LOW_WORD(low,x);
				if (((hx & 0xfffff) | low) != 0)
					return x + x;
				else
					return (xsb == 0) ? x : -1.0;
			}
			if (x > o_threshold)
				return huge * huge;
		}
		if (xsb != 0)
		{
			if (x + tiny < 0.0)
				return tiny - one;
		}
	}

	if (hx > 0x3fd62e42)
	{
		if (hx < 0x3FF0A2B2)
		{
			if (xsb == 0)
			{
				hi = x - ln2_hi;
				lo = ln2_lo;
				k = 1;
			}
			else
			{
				hi = x + ln2_hi;
				lo = -ln2_lo;
				k = -1;
			}
		}
		else
		{
			k = invln2 * x + ((xsb == 0) ? 0.5 : -0.5);
			t = k;
			hi = x - t * ln2_hi;
			lo = t * ln2_lo;
		}
		x = hi - lo;
		c = (hi - x) - lo;
	}
	else if (hx < 0x3c900000)
	{
		t = huge + x;
		return x - (t - (huge + x));
	}
	else
		k = 0;

	hfx = 0.5 * x;
	hxs = x * hfx;
	r1 = one + hxs * (Q1 + hxs * (Q2 + hxs * (Q3 + hxs * (Q4 + hxs * Q5))));
	t = 3.0 - r1 * hfx;
	e = hxs * ((r1 - t) / (6.0 - x * t));
	if (k == 0)
		return x - (x * e - hxs);
	else
	{
		e = (x * (e - c) - c);
		e -= hxs;
		if (k == -1)
			return 0.5 * (x - e) - 0.5;
		if (k == 1)
		{
			if (x < -0.25)
				return -2.0 * (e - (x + 0.5));
			else
				return one + 2.0 * (x - e);
		}
		if (k <= -2 || k > 56)
		{
			u32_t high;
			y = one - (e - x);
			GET_HIGH_WORD(high,y);
			SET_HIGH_WORD(y,high+(k<<20));
			return y - one;
		}
		t = one;
		if (k < 20)
		{
			u32_t high;
			SET_HIGH_WORD(t,0x3ff00000 - (0x200000>>k));
			y = t - (e - x);
			GET_HIGH_WORD(high,y);
			SET_HIGH_WORD(y,high+(k<<20));
		}
		else
		{
Пример #20
0
double attribute_hidden __ieee754_hypot(double x, double y)
{
    double a=x,b=y,t1,t2,y1,y2,w;
    int32_t j,k,ha,hb;

    GET_HIGH_WORD(ha,x);
    ha &= 0x7fffffff;
    GET_HIGH_WORD(hb,y);
    hb &= 0x7fffffff;
    if(hb > ha) {
        a=y;
        b=x;
        j=ha;
        ha=hb;
        hb=j;
    }
    else {
        a=x;
        b=y;
    }
    SET_HIGH_WORD(a,ha);	/* a <- |a| */
    SET_HIGH_WORD(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 */
            u_int32_t low;
            w = a+b;			/* for sNaN */
            GET_LOW_WORD(low,a);
            if(((ha&0xfffff)|low)==0) w = a;
            GET_LOW_WORD(low,b);
            if(((hb^0x7ff00000)|low)==0) w = b;
            return w;
        }
        /* scale a and b by 2**-600 */
        ha -= 0x25800000;
        hb -= 0x25800000;
        k += 600;
        SET_HIGH_WORD(a,ha);
        SET_HIGH_WORD(b,hb);
    }
    if(hb < 0x20b00000) {	/* b < 2**-500 */
        if(hb <= 0x000fffff) {	/* subnormal b or 0 */
            u_int32_t low;
            GET_LOW_WORD(low,b);
            if((hb|low)==0) return a;
            t1=0;
            SET_HIGH_WORD(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;
            SET_HIGH_WORD(a,ha);
            SET_HIGH_WORD(b,hb);
        }
    }
    /* medium size a and b */
    w = a-b;
    if (w>b) {
        t1 = 0;
        SET_HIGH_WORD(t1,ha);
        t2 = a-t1;
        w  = __ieee754_sqrt(t1*t1-(b*(-b)-t2*(a+t1)));
    } else {
        a  = a+a;
        y1 = 0;
        SET_HIGH_WORD(y1,hb);
        y2 = b - y1;
        t1 = 0;
        SET_HIGH_WORD(t1,ha+0x00100000);
        t2 = a - t1;
        w  = __ieee754_sqrt(t1*y1-(w*(-w)-(t1*y2+t2*b)));
    }
    if(k!=0) {
        u_int32_t high;
        t1 = 1.0;
        GET_HIGH_WORD(high,t1);
        SET_HIGH_WORD(t1,high+(k<<20));
        return t1*w;
    } else return w;
}