示例#1
0
文件: sinh.c 项目: EtchedPixels/FUZIX
double sinh(double x)
{
	double t, h;
	int32_t ix, jx;

	/* 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 */
			/* raise inexact, return x */
			if (huge+x > 1.0)
				return x;
		t = expm1(fabs(x));
		if (ix < 0x3ff00000)
			return h*(2.0*t - t*t/(t+1.0));
		return h*(t + t/(t+1.0));
	}

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

	/* |x| in [log(maxdouble), overflowthresold] */
	if (ix <= 0x408633CE)
		return h * 2.0 * __expo2(fabs(x)); /* h is for sign only */

	/* |x| > overflowthresold, sinh(x) overflow */
	return x*huge;
}
示例#2
0
double sinh(double x)
{
	double t,w,h;
	int32_t ix,jx;
	u_int32_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<=(u_int32_t)0x8fb9f87d))) {
	    w = __ieee754_exp(0.5*fabs(x));
	    t = h*w;
	    return t*w;
	}

    /* |x| > overflowthresold, sinh(x) overflow */
	return x*shuge;
}
示例#3
0
文件: cosh.c 项目: KGG814/AOS
double cosh(double x)
{
	double t, w;
	int32_t ix;

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

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

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

	/* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|))/2; */
	if (ix < 0x40360000) {
		t = exp(fabs(x));
		return 0.5*t + 0.5/t;
	}

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

	/* |x| in [log(maxdouble), overflowthresold] */
	if (ix <= 0x408633CE)
		return __expo2(fabs(x));

	/* |x| > overflowthresold, cosh(x) overflow */
	return huge*huge;
}
示例#4
0
double
tan(double x)
{
	double y[2],z=0.0;
	int32_t n, ix;

    /* High word of x. */
	GET_HIGH_WORD(ix,x);

    /* |x| ~< pi/4 */
	ix &= 0x7fffffff;
	if(ix <= 0x3fe921fb) return __kernel_tan(x,z,1);

    /* tan(Inf or NaN) is NaN */
	else if (ix>=0x7ff00000) return x-x;		/* NaN */

    /* argument reduction needed */
	else {
	    n = __libm_rem_pio2(x,y);
	    return __kernel_tan(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
							-1 -- n odd */
	}
}
示例#5
0
double
__ieee754_cosh(double x)
{
	double t,w;
	int32_t ix;

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

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

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

    /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */
	if (ix < 0x40360000) {
		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] */
	if (ix<=0x408633CE)
	    return __ldexp_exp(fabs(x), -1);

    /* |x| > overflowthresold, cosh(x) overflow */
	return huge*huge;
}
示例#6
0
文件: tanh.c 项目: Philippe12/lichee
double tanh(double x)
{
    double t, z;
    s32_t jx, ix;

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

    if (ix >= 0x7ff00000)
    {
        if (jx >= 0)
            return one / x + one;
        else
            return one / x - one;
    }

    if (ix < 0x40360000)
    {
        if (ix < 0x3c800000)
            return x * (one + x);
        if (ix >= 0x3ff00000)
        {
            t = expm1(two * fabs(x));
            z = one - two / (t + two);
        }
        else
        {
            t = expm1(-two * fabs(x));
            z = -t / (t + two);
        }
    }
    else
    {
        z = one - tiny;
    }
    return (jx >= 0) ? z : -z;
}
示例#7
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;
		}
示例#8
0
double
__asinh(double x)
{
	double w;
	int32_t hx,ix;
	GET_HIGH_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(__builtin_expect(ix< 0x3e300000, 0)) {	/* |x|<2**-28 */
	    if(huge+x>one) return x;	/* return x inexact except 0 */
	}
	if(__builtin_expect(ix>0x41b00000, 0)) {	/* |x| > 2**28 */
	    if(ix>=0x7ff00000) return x+x;	/* x is inf or NaN */
	    w = __ieee754_log(fabs(x))+ln2;
	} else {
	    double xa = fabs(x);
	    if (ix>0x40000000) {	/* 2**28 > |x| > 2.0 */
		w = __ieee754_log(2.0*xa+one/(__ieee754_sqrt(xa*xa+one)+xa));
	    } else {		/* 2.0 > |x| > 2**-28 */
		double t = xa*xa;
		w =__log1p(xa+t/(one+__ieee754_sqrt(one+t)));
	    }
	}
	return __copysign(w, x);
}
示例#9
0
double attribute_hidden __kernel_cos(double x, double y)
{
    double a,hz,z,r,qx;
    int32_t ix;
    GET_HIGH_WORD(ix,x);
    ix &= 0x7fffffff;			/* ix = |x|'s high word*/
    if(ix<0x3e400000) {			/* if x < 2**27 */
        if(((int)x)==0) return one;		/* generate inexact */
    }
    z  = x*x;
    r  = z*(C1+z*(C2+z*(C3+z*(C4+z*(C5+z*C6)))));
    if(ix < 0x3FD33333) 			/* if |x| < 0.3 */
        return one - (0.5*z - (z*r - x*y));
    else {
        if(ix > 0x3fe90000) {		/* x > 0.78125 */
            qx = 0.28125;
        } else {
            INSERT_WORDS(qx,ix-0x00200000,0);	/* x/4 */
        }
        hz = 0.5*z-qx;
        a  = one-qx;
        return a - (hz - (z*r-x*y));
    }
}
示例#10
0
int
__issignaling (double x)
{
#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
  u_int32_t hxi;
  GET_HIGH_WORD (hxi, x);
  /* We only have to care about the high-order bit of x's significand, because
     having it set (sNaN) already makes the significand different from that
     used to designate infinity.  */
  return (hxi & 0x7ff80000) == 0x7ff80000;
#else
  u_int32_t hxi, lxi;
  EXTRACT_WORDS (hxi, lxi, x);
  /* To keep the following comparison simple, toggle the quiet/signaling bit,
     so that it is set for sNaNs.  This is inverse to IEEE 754-2008 (as well as
     common practice for IEEE 754-1985).  */
  hxi ^= 0x00080000;
  /* If lxi != 0, then set any suitable bit of the significand in hxi.  */
  hxi |= (lxi | -lxi) >> 31;
  /* We have to compare for greater (instead of greater or equal), because x's
     significand being all-zero designates infinity not NaN.  */
  return (hxi & 0x7fffffff) > 0x7ff80000;
#endif
}
示例#11
0
文件: k_tan.c 项目: ArcEye/RTAI-2
	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)));
	}
示例#12
0
long double
hypotl(long double x, long double y)
{
	long double a=x,b=y,t1,t2,y1,y2,w;
	int32_t j,k,ha,hb;

	GET_HIGH_WORD(ha,x);
	ha &= 0x7fff;
	GET_HIGH_WORD(hb,y);
	hb &= 0x7fff;
	if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;}
	a = fabsl(a);
	b = fabsl(b);
	if((ha-hb)>DESW(MANT_DIG+7)) {return a+b;} /* x/y > 2**(MANT_DIG+7) */
	k=0;
	if(ha > ESW(MAX_EXP/2-12)) {	/* a>2**(MAX_EXP/2-12) */
	   if(ha >= ESW(MAX_EXP)) {	/* Inf or NaN */
	       man_t manh, manl;
	       /* Use original arg order iff result is NaN; quieten sNaNs. */
	       w = fabsl(x+0.0)-fabsl(y+0.0);
	       GET_LDBL_MAN(manh,manl,a);
	       if (manh == LDBL_NBIT && manl == 0) w = a;
	       GET_LDBL_MAN(manh,manl,b);
	       if (hb >= ESW(MAX_EXP) && manh == LDBL_NBIT && manl == 0) w = b;
	       return w;
	   }
	   /* scale a and b by 2**-(MAX_EXP/2+88) */
	   ha -= DESW(MAX_EXP/2+88); hb -= DESW(MAX_EXP/2+88);
	   k += MAX_EXP/2+88;
	   SET_HIGH_WORD(a,ha);
	   SET_HIGH_WORD(b,hb);
	}
	if(hb < ESW(-(MAX_EXP/2-12))) {	/* b < 2**-(MAX_EXP/2-12) */
	    if(hb <= 0) {		/* subnormal b or 0 */
	        man_t manh, manl;
		GET_LDBL_MAN(manh,manl,b);
		if((manh|manl)==0) return a;
		t1=0;
		SET_HIGH_WORD(t1,ESW(MAX_EXP-2));	/* t1=2^(MAX_EXP-2) */
		b *= t1;
		a *= t1;
		k -= MAX_EXP-2;
	    } else {		/* scale a and b by 2^(MAX_EXP/2+88) */
		ha += DESW(MAX_EXP/2+88);
		hb += DESW(MAX_EXP/2+88);
		k -= MAX_EXP/2+88;
		SET_HIGH_WORD(a,ha);
		SET_HIGH_WORD(b,hb);
	    }
	}
    /* medium size a and b */
	w = a-b;
	if (w>b) {
	    t1 = a;
	    union IEEEl2bits uv;
	    uv.e = t1; uv.bits.manl = 0; t1 = uv.e;
	    t2 = a-t1;
	    w  = sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
	} else {
	    a  = a+a;
	    y1 = b;
	    union IEEEl2bits uv;
	    uv.e = y1; uv.bits.manl = 0; y1 = uv.e;
	    y2 = b - y1;
	    t1 = a;
	    uv.e = t1; uv.bits.manl = 0; t1 = uv.e;
	    t2 = a - t1;
	    w  = sqrtl(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+DESW(k));
	    return t1*w;
	} else return w;
}
示例#13
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;
}
示例#14
0
文件: log2.c 项目: EtchedPixels/FUZIX
double log2(double x)
{
	double f,hfsq,hi,lo,r,val_hi,val_lo,w,y;
	int32_t i,k,hx;
	uint32_t lx;

	EXTRACT_WORDS(hx, lx, x);

	k = 0;
	if (hx < 0x00100000) {  /* x < 2**-1022  */
		if (((hx&0x7fffffff)|lx) == 0)
			return -two54/0.0;  /* log(+-0)=-inf */
		if (hx < 0)
			return (x-x)/0.0;   /* log(-#) = NaN */
		/* subnormal number, scale up x */
		k -= 54;
		x *= two54;
		GET_HIGH_WORD(hx, x);
	}
	if (hx >= 0x7ff00000)
		return x+x;
	if (hx == 0x3ff00000 && lx == 0)
		return 0.0;  /* log(1) = +0 */
	k += (hx>>20) - 1023;
	hx &= 0x000fffff;
	i = (hx+0x95f64) & 0x100000;
	SET_HIGH_WORD(x, hx|(i^0x3ff00000));  /* normalize x or x/2 */
	k += i>>20;
	y = (double)k;
	f = x - 1.0;
	hfsq = 0.5*f*f;
	r = __log1p(f);

	/*
	 * f-hfsq must (for args near 1) be evaluated in extra precision
	 * to avoid a large cancellation when x is near sqrt(2) or 1/sqrt(2).
	 * This is fairly efficient since f-hfsq only depends on f, so can
	 * be evaluated in parallel with R.  Not combining hfsq with R also
	 * keeps R small (though not as small as a true `lo' term would be),
	 * so that extra precision is not needed for terms involving R.
	 *
	 * Compiler bugs involving extra precision used to break Dekker's
	 * theorem for spitting f-hfsq as hi+lo, unless double_t was used
	 * or the multi-precision calculations were avoided when double_t
	 * has extra precision.  These problems are now automatically
	 * avoided as a side effect of the optimization of combining the
	 * Dekker splitting step with the clear-low-bits step.
	 *
	 * y must (for args near sqrt(2) and 1/sqrt(2)) be added in extra
	 * precision to avoid a very large cancellation when x is very near
	 * these values.  Unlike the above cancellations, this problem is
	 * specific to base 2.  It is strange that adding +-1 is so much
	 * harder than adding +-ln2 or +-log10_2.
	 *
	 * This uses Dekker's theorem to normalize y+val_hi, so the
	 * compiler bugs are back in some configurations, sigh.  And I
	 * don't want to used double_t to avoid them, since that gives a
	 * pessimization and the support for avoiding the pessimization
	 * is not yet available.
	 *
	 * The multi-precision calculations for the multiplications are
	 * routine.
	 */
	hi = f - hfsq;
	SET_LOW_WORD(hi, 0);
	lo = (f - hi) - hfsq + r;
	val_hi = hi*ivln2hi;
	val_lo = (lo+hi)*ivln2lo + lo*ivln2hi;

	/* spadd(val_hi, val_lo, y), except for not using double_t: */
	w = y + val_hi;
	val_lo += (y - w) + val_hi;
	val_hi = w;

	return val_lo + val_hi;
}
示例#15
0
文件: s_pow.c 项目: behnaaz/jerl
double pow (double x, double y)
{
  double d, k, t, r = 1.0;
  int n, sign, exponent_is_even_int = 0;
  __uint32_t px;

  GET_HIGH_WORD (px, x);

  k = modf (y, &d);

  if (k == 0.0)
    {
      /* Exponent y is an integer. */
      if (modf (ldexp (y, -1), &t))
        {
          /* y is odd. */
          exponent_is_even_int = 0;
        }
      else
        {
          /* y is even. */
          exponent_is_even_int = 1;
        }
    }

  if (x == 0.0 && y <= 0.0)
    {
      errno = EDOM;
    }
  else if ((t = y * log (fabs (x))) >= BIGX) 
    {
      errno = ERANGE;
      if (px & 0x80000000) 
        {
          /* x is negative. */
          if (k) 
            {
              /* y is not an integer. */
              errno = EDOM;
              x = 0.0;
            }
          else if (exponent_is_even_int)
            x = z_infinity.d;
          else
            x = -z_infinity.d;
        }
      else
        {
          x = z_infinity.d;
        }
    }
  else if (t < SMALLX)
    {
      errno = ERANGE;
      x = 0.0;
    }
  else 
    {
      if ( !k && fabs(d) <= 32767 ) 
        {
          n = (int) d;

          if ((sign = (n < 0)))
            n = -n;

          while ( n > 0 ) 
            {
              if ((unsigned int) n % 2) 
                r *= x;
              x *= x;
              n = (unsigned int) n / 2;
            }

          if (sign)
            r = 1.0 / r;

          return r;
        }
      else 
        {
          if ( px & 0x80000000 ) 
            {
              /* x is negative. */
              if ( k ) 
                {
                  /* y is not an integer. */
                  errno = EDOM;
                  return 0.0;
                }
            }

          x = exp (t);

          if (!exponent_is_even_int)
            {
              if (px & 0x80000000)
                {
                  /* y is an odd integer, and x is negative,
                     so the result is negative. */
                  GET_HIGH_WORD (px, x);
                  px |= 0x80000000;
                  SET_HIGH_WORD (x, px);
                }
            }
        }
    }

  return x;
}
示例#16
0
int __finite(double x)
{
	int32_t hx;
	GET_HIGH_WORD(hx,x);
	return (int)((u_int32_t)((hx&0x7fffffff)-0x7ff00000)>>31);
}
示例#17
0
double pow (double x, double y)
{
  double d, t, r = 1.0;
  int n, k, sign = 0;
  __uint32_t px;

  GET_HIGH_WORD (px, x);

  k = modf (y, &d);
  if (k == 0.0) 
    {
      if (modf (ldexp (y, -1), &t))
        sign = 0;
      else
        sign = 1; 
    }
  
  if (x == 0.0 && y <= 0.0) 
    errno = EDOM;

  else if ((t = y * log (fabs (x))) >= BIGX) 
    {
      errno = ERANGE;
      if (px & 0x80000000) 
        {
          if (!k) 
            {
              errno = EDOM;
              x = 0.0;
            }
          else if (sign)
            x = -z_infinity.d;
          else
            x =  z_infinity.d;
        }

    else 
      x = z_infinity.d;
  }

  else if (t < SMALLX)
    {
      errno = ERANGE;
      x = 0.0;
    }

  else 
    {
      if ( k && fabs(d) <= 32767 ) 
        {
          n = (int) d;

          if (sign = (n < 0))
            n = -n;

          while ( n > 0 ) 
            {
              if ((unsigned int) n % 2) 
                r *= x;
              x *= x;
              n = (unsigned int) n / 2;
            }

          if (sign)
            r = 1.0 / r;

          return r;
        }
		
      else 
        {
          if ( px & 0x80000000 ) 
            {
              if ( !k ) 
                {
                  errno = EDOM;
                  return 0.0;
                }
            }

          x = exp (t);
          /*
            // The usage of sign over here is incorrect.
            if ( sign ) 
            { 
            px ^= 0x80000000;
            SET_HIGH_WORD (x, px);
            }
          */
        }
      }

  return x;
}
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
		{
示例#19
0
文件: e_log.c 项目: enishant/mx
double
__ieee754_log(double x)
{
    double hfsq,f,s,z,R,w,t1,t2,dk;
    int32_t k,hx,i,j;
    uint32_t lx;

    EXTRACT_WORDS(hx,lx,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 */
        GET_HIGH_WORD(hx,x);
    }
    if (hx >= 0x7ff00000) return x+x;
    k += (hx>>20)-1023;
    hx &= 0x000fffff;
    i = (hx+0x95f64)&0x100000;
    SET_HIGH_WORD(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);
    }
}
示例#20
0
文件: s_cbrt.c 项目: vtjnash/openlibm
double
cbrt(double x)
{
	int32_t	hx;
	union {
	    double value;
	    u_int64_t bits;
	} u;
	double r,s,t=0.0,w;
	u_int32_t sign;
	u_int32_t high,low;

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

    /*
     * Rough cbrt to 5 bits:
     *    cbrt(2**e*(1+m) ~= 2**(e/3)*(1+(e%3+m)/3)
     * where e is integral and >= 0, m is real and in [0, 1), and "/" and
     * "%" are integer division and modulus with rounding towards minus
     * infinity.  The RHS is always >= the LHS and has a maximum relative
     * error of about 1 in 16.  Adding a bias of -0.03306235651 to the
     * (e%3+m)/3 term reduces the error to about 1 in 32. With the IEEE
     * floating point representation, for finite positive normal values,
     * ordinary integer divison of the value in bits magically gives
     * almost exactly the RHS of the above provided we first subtract the
     * exponent bias (1023 for doubles) and later add it back.  We do the
     * subtraction virtually to keep e >= 0 so that ordinary integer
     * division rounds towards minus infinity; this is also efficient.
     */
	if(hx<0x00100000) { 		/* zero or subnormal? */
	    if((hx|low)==0)
		return(x);		/* cbrt(0) is itself */
	    SET_HIGH_WORD(t,0x43500000); /* set t= 2**54 */
	    t*=x;
	    GET_HIGH_WORD(high,t);
	    INSERT_WORDS(t,sign|((high&0x7fffffff)/3+B2),0);
	} else
	    INSERT_WORDS(t,sign|(hx/3+B1),0);

    /*
     * New cbrt to 23 bits:
     *    cbrt(x) = t*cbrt(x/t**3) ~= t*P(t**3/x)
     * where P(r) is a polynomial of degree 4 that approximates 1/cbrt(r)
     * to within 2**-23.5 when |r - 1| < 1/10.  The rough approximation
     * has produced t such than |t/cbrt(x) - 1| ~< 1/32, and cubing this
     * gives us bounds for r = t**3/x.
     *
     * Try to optimize for parallel evaluation as in k_tanf.c.
     */
	r=(t*t)*(t/x);
	t=t*((P0+r*(P1+r*P2))+((r*r)*r)*(P3+r*P4));

    /*
     * Round t away from zero to 23 bits (sloppily except for ensuring that
     * the result is larger in magnitude than cbrt(x) but not much more than
     * 2 23-bit ulps larger).  With rounding towards zero, the error bound
     * would be ~5/6 instead of ~4/6.  With a maximum error of 2 23-bit ulps
     * in the rounded t, the infinite-precision error in the Newton
     * approximation barely affects third digit in the final error
     * 0.667; the error in the rounded t can be up to about 3 23-bit ulps
     * before the final error is larger than 0.667 ulps.
     */
	u.value=t;
	u.bits=(u.bits+0x80000000)&0xffffffffc0000000ULL;
	t=u.value;

    /* one step Newton iteration to 53 bits with error < 0.667 ulps */
	s=t*t;				/* t*t is exact */
	r=x/s;				/* error <= 0.5 ulps; |r| < |t| */
	w=t+t;				/* t+t is exact */
	r=(r-t)/(w+r);			/* r-t is exact; w+r ~= 3*t */
	t=t+t*r;			/* error <= 0.5 + 0.5/3 + epsilon */

	return(t);
}
示例#21
0
文件: expm1.c 项目: HuaiYuSched/pok
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 {
示例#22
0
double
__ieee754_j1 (double x)
{
  double z, s, c, ss, cc, r, u, v, y, r1, r2, s1, s2, s3, z2, z4;
  int32_t hx, ix;

  GET_HIGH_WORD (hx, x);
  ix = hx & 0x7fffffff;
  if (__glibc_unlikely (ix >= 0x7ff00000))
    return one / x;
  y = fabs (x);
  if (ix >= 0x40000000)         /* |x| >= 2.0 */
    {
      __sincos (y, &s, &c);
      ss = -s - c;
      cc = s - c;
      if (ix < 0x7fe00000)           /* make sure y+y not overflow */
	{
	  z = __cos (y + y);
	  if ((s * c) > zero)
	    cc = z / ss;
	  else
	    ss = z / cc;
	}
      /*
       * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
       * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
       */
      if (ix > 0x48000000)
	z = (invsqrtpi * cc) / sqrt (y);
      else
	{
	  u = pone (y); v = qone (y);
	  z = invsqrtpi * (u * cc - v * ss) / sqrt (y);
	}
      if (hx < 0)
	return -z;
      else
	return z;
    }
  if (__glibc_unlikely (ix < 0x3e400000))                  /* |x|<2**-27 */
    {
      if (huge + x > one)                 /* inexact if x!=0 necessary */
	{
	  double ret = math_narrow_eval (0.5 * x);
	  math_check_force_underflow (ret);
	  if (ret == 0 && x != 0)
	    __set_errno (ERANGE);
	  return ret;
	}
    }
  z = x * x;
  r1 = z * R[0]; z2 = z * z;
  r2 = R[1] + z * R[2]; z4 = z2 * z2;
  r = r1 + z2 * r2 + z4 * R[3];
  r *= x;
  s1 = one + z * S[1];
  s2 = S[2] + z * S[3];
  s3 = S[4] + z * S[5];
  s = s1 + z2 * s2 + z4 * s3;
  return (x * 0.5 + r / s);
}
示例#23
0
文件: e_j0.c 项目: riscv/riscv-glibc
double
__ieee754_j0 (double x)
{
  double z, s, c, ss, cc, r, u, v, r1, r2, s1, s2, z2, z4;
  int32_t hx, ix;

  GET_HIGH_WORD (hx, x);
  ix = hx & 0x7fffffff;
  if (ix >= 0x7ff00000)
    return one / (x * x);
  x = fabs (x);
  if (ix >= 0x40000000)         /* |x| >= 2.0 */
    {
      __sincos (x, &s, &c);
      ss = s - c;
      cc = s + c;
      if (ix < 0x7fe00000)           /* make sure x+x not overflow */
	{
	  z = -__cos (x + x);
	  if ((s * c) < zero)
	    cc = z / ss;
	  else
	    ss = z / cc;
	}
      /*
       * 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 > 0x48000000)
	z = (invsqrtpi * cc) / __ieee754_sqrt (x);
      else
	{
	  u = pzero (x); v = qzero (x);
	  z = invsqrtpi * (u * cc - v * ss) / __ieee754_sqrt (x);
	}
      return z;
    }
  if (ix < 0x3f200000)          /* |x| < 2**-13 */
    {
      math_force_eval (huge + x);       /* raise inexact if x != 0 */
      if (ix < 0x3e400000)
	return one;                     /* |x|<2**-27 */
      else
	return one - 0.25 * x * x;
    }
  z = x * x;
  r1 = z * R[2]; z2 = z * z;
  r2 = R[3] + z * R[4]; z4 = z2 * z2;
  r = r1 + z2 * r2 + z4 * R[5];
  s1 = one + z * S[1];
  s2 = S[2] + z * S[3];
  s = s1 + z2 * s2 + z4 * S[4];
  if (ix < 0x3FF00000)          /* |x| < 1.00 */
    {
      return one + z * (-0.25 + (r / s));
    }
  else
    {
      u = 0.5 * x;
      return ((one + u) * (one - u) + z * (r / s));
    }
}
示例#24
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;
}
示例#25
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;
}