示例#1
0
int
totalorderl (long double x, long double y)
{
  int16_t expx, expy;
  uint32_t hx, hy;
  uint32_t lx, ly;
  GET_LDOUBLE_WORDS (expx, hx, lx, x);
  GET_LDOUBLE_WORDS (expy, hy, ly, y);
  if (LDBL_MIN_EXP == -16382)
    {
      /* M68K variant: for the greatest exponent, the high mantissa
	 bit is not significant and both values of it are valid, so
	 set it before comparing.  For the Intel variant, only one
	 value of the high mantissa bit is valid for each exponent, so
	 this is not necessary.  */
      if ((expx & 0x7fff) == 0x7fff)
	hx |= 0x80000000;
      if ((expy & 0x7fff) == 0x7fff)
	hy |= 0x80000000;
    }
#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
# error not implemented
#endif
  uint32_t x_sign = expx >> 15;
  uint32_t y_sign = expy >> 15;
  expx ^= x_sign >> 17;
  hx ^= x_sign;
  lx ^= x_sign;
  expy ^= y_sign >> 17;
  hy ^= y_sign;
  ly ^= y_sign;
  return expx < expy || (expx == expy && (hx < hy || (hx == hy && lx <= ly)));
}
示例#2
0
文件: s_tanl.c 项目: AubrCool/glibc
long double __tanl(long double x)
{
	long double y[2],z=0.0;
	int32_t n, se, i0, i1;

    /* High word of x. */
	GET_LDOUBLE_WORDS(se,i0,i1,x);

    /* |x| ~< pi/4 */
	se &= 0x7fff;
	if(se <= 0x3ffe) return __kernel_tanl(x,z,1);

    /* tan(Inf or NaN) is NaN */
	else if (se==0x7fff) {
	  if (i1 == 0 && i0 == 0x80000000)
	    __set_errno (EDOM);
	  return x-x;
	}

    /* argument reduction needed */
	else {
	    n = __ieee754_rem_pio2l(x,y);
	    return __kernel_tanl(y[0],y[1],1-((n&1)<<1)); /*   1 -- n even
							-1 -- n odd */
	}
}
示例#3
0
long double
__ieee754_gammal_r (long double x, int *signgamp)
{
  /* We don't have a real gamma implementation now.  We'll use lgamma
     and the exp function.  But due to the required boundary
     conditions we must check some values separately.  */
  u_int32_t es, hx, lx;

  GET_LDOUBLE_WORDS (es, hx, lx, x);

  if (((es & 0x7fff) | hx | lx) == 0)
    {
      /* Return value for x == 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return x / x;
    }
  if (es == 0xffffffff && ((hx & 0x7fffffff) | lx) == 0)
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }
  if ((es & 0x7fff) == 0x7fff && ((hx & 0x7fffffff) | lx) != 0)
    /* NaN, return it.  */
    return x;
  if ((es & 0x8000) != 0 && x < 0xffffffff && __rintl (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }

  /* XXX FIXME.  */
  return __ieee754_expl (__ieee754_lgammal_r (x, signgamp));
}
示例#4
0
int
__isinf_nsl (long double x)
{
    int32_t se,hx,lx;
    GET_LDOUBLE_WORDS(se,hx,lx,x);
    return !(((se & 0x7fff) ^ 0x7fff) | lx | (hx & 0x7fffffff));
}
示例#5
0
long long int
__llrintl (long double x)
{
  int32_t e, s;
  u_int32_t h, l;
  long long int result;

  x = __m81_u(__rintl) (x);

  GET_LDOUBLE_WORDS (e, h, l, x);

  s = e;
  e = (e & 0x7fff) - 0x3fff;
  if (e < 0)
    return 0;

  if (e < 63)
    {
      if (e > 31)
	{
	  l >>= 63 - e;
	  l |= h << (e - 31);
	  h >>= 63 - e;
	  result = ((long long int) h << 32) | l;
	}
      else
示例#6
0
文件: s_cosl.c 项目: AubrCool/glibc
long double __cosl(long double x)
{
	long double y[2],z=0.0;
	int32_t n, se, i0, i1;

    /* High word of x. */
	GET_LDOUBLE_WORDS(se,i0,i1,x);

    /* |x| ~< pi/4 */
	se &= 0x7fff;
	if(se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2))
	  return __kernel_cosl(x,z);

    /* cos(Inf or NaN) is NaN */
	else if (se==0x7fff) {
	  if (i1 == 0 && i0 == 0x80000000)
	    __set_errno (EDOM);
	  return x-x;
	}

    /* argument reduction needed */
	else {
	    n = __ieee754_rem_pio2l(x,y);
	    switch(n&3) {
		case 0: return  __kernel_cosl(y[0],y[1]);
		case 1: return -__kernel_sinl(y[0],y[1],1);
		case 2: return -__kernel_cosl(y[0],y[1]);
		default:
		        return  __kernel_sinl(y[0],y[1],1);
	    }
	}
}
示例#7
0
double __nexttoward(double x, long double y)
{
	int32_t hx,ix,iy;
	u_int32_t lx,hy,ly,esy;

	EXTRACT_WORDS(hx,lx,x);
	GET_LDOUBLE_WORDS(esy,hy,ly,y);
	ix = hx&0x7fffffff;		/* |x| */
	iy = esy&0x7fff;		/* |y| */

	/* Intel's extended format has the normally implicit 1 explicit
	   present.  Sigh!  */
	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
	   ((iy>=0x7fff)&&((hy&0x7fffffff)|ly)!=0))        /* y is nan */
	   return x+y;
	if((long double) x==y) return y;	/* x=y, return y */
	if((ix|lx)==0) {			/* x == 0 */
	    double u;
	    INSERT_WORDS(x,(esy&0x8000)<<16,1); /* return +-minsub */
	    u = math_opt_barrier (x);
	    u = u * u;
	    math_force_eval (u);		/* raise underflow flag */
	    return x;
	}
	if(hx>=0) {				/* x > 0 */
	    if (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 (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) {
	  double u = x+x;			/* overflow  */
	  math_force_eval (u);
	}
	if(hy<0x00100000) {
	    double u = x*x;			/* underflow */
	    math_force_eval (u);		/* raise underflow flag */
	}
	INSERT_WORDS(x,hx,lx);
	return x;
}
示例#8
0
文件: erfl.c 项目: GregorR/musl
long double erfl(long double x)
{
	long double R, S, P, Q, s, y, z, r;
	int32_t ix, i;
	uint32_t se, i0, i1;

	GET_LDOUBLE_WORDS(se, i0, i1, x);
	ix = se & 0x7fff;

	if (ix >= 0x7fff) {  /* erf(nan)=nan */
		i = ((se & 0xffff) >> 15) << 1;
		return (long double)(1 - i) + 1.0 / x;  /* erf(+-inf)=+-1 */
	}
示例#9
0
void
__sincosl (long double x, long double *sinx, long double *cosx)
{
  int32_t se, i0, i1 __attribute__ ((unused));

  /* High word of x. */
  GET_LDOUBLE_WORDS (se, i0, i1, x);

  /* |x| ~< pi/4 */
  se &= 0x7fff;
  if (se < 0x3ffe || (se == 0x3ffe && i0 <= 0xc90fdaa2))
    {
      *sinx = __kernel_sinl (x, 0.0, 0);
      *cosx = __kernel_cosl (x, 0.0);
    }
  else if (se == 0x7fff)
    {
      /* sin(Inf or NaN) is NaN */
      *sinx = *cosx = x - x;
      if (isinf (x))
	__set_errno (EDOM);
    }
  else
    {
      /* Argument reduction needed.  */
      long double y[2];
      int n;

      n = __ieee754_rem_pio2l (x, y);
      switch (n & 3)
	{
	case 0:
	  *sinx = __kernel_sinl (y[0], y[1], 1);
	  *cosx = __kernel_cosl (y[0], y[1]);
	  break;
	case 1:
	  *sinx = __kernel_cosl (y[0], y[1]);
	  *cosx = -__kernel_sinl (y[0], y[1], 1);
	  break;
	case 2:
	  *sinx = -__kernel_sinl (y[0], y[1], 1);
	  *cosx = -__kernel_cosl (y[0], y[1]);
	  break;
	default:
	  *sinx = -__kernel_cosl (y[0], y[1]);
	  *cosx = __kernel_sinl (y[0], y[1], 1);
	  break;
	}
    }
}
示例#10
0
float __nexttowardf(float x, long double y)
{
	int32_t hx,ix,iy;
	uint32_t hy,ly,esy;

	GET_FLOAT_WORD(hx,x);
	GET_LDOUBLE_WORDS(esy,hy,ly,y);
	ix = hx&0x7fffffff;		/* |x| */
	iy = esy&0x7fff;		/* |y| */

	if((ix>0x7f800000) ||			/* x is nan */
	   (iy>=0x7fff&&((hy|ly)!=0)))		/* y is nan */
	   return x+y;
	if((long double) x==y) return y;	/* x=y, return y */
	if(ix==0) {				/* x == 0 */
	    float u;
	    SET_FLOAT_WORD(x,((esy&0x8000)<<16)|1);/* return +-minsub*/
	    u = math_opt_barrier (x);
	    u = u * u;
	    math_force_eval (u);		/* raise underflow flag */
	    return x;
	}
	if(hx>=0) {				/* x > 0 */
	    if(x > y) {				/* x -= ulp */
		hx -= 1;
	    } else {				/* x < y, x += ulp */
		hx += 1;
	    }
	} else {				/* x < 0 */
	    if(x < y) {				/* x -= ulp */
		hx -= 1;
	    } else {				/* x > y, x += ulp */
		hx += 1;
	    }
	}
	hy = hx&0x7f800000;
	if(hy>=0x7f800000) {
	  float u = x+x;			/* overflow  */
	  math_force_eval (u);
	  __set_errno (ERANGE);
	}
	if(hy<0x00800000) {
	    float u = x*x;			/* underflow */
	    math_force_eval (u);		/* raise underflow flag */
	    __set_errno (ERANGE);
	}
	SET_FLOAT_WORD(x,hx);
	return x;
}
示例#11
0
文件: e_sinhl.c 项目: hwoarang/glibc
long double
__ieee754_sinhl(long double x)
{
	long double t,w,h;
	u_int32_t jx,ix,i0,i1;

    /* Words of |x|. */
	GET_LDOUBLE_WORDS(jx,i0,i1,x);
	ix = jx&0x7fff;

    /* x is INF or NaN */
	if(__builtin_expect(ix==0x7fff, 0)) return x+x;

	h = 0.5;
	if (jx & 0x8000) h = -h;
    /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */
	if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */
	    if (ix<0x3fdf) {		/* |x|<2**-32 */
		if (fabsl (x) < LDBL_MIN)
		  {
		    long double force_underflow = x * x;
		    math_force_eval (force_underflow);
		  }
		if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
	    }
	    t = __expm1l(fabsl(x));
	    if(ix<0x3fff) return h*(2.0*t-t*t/(t+one));
	    return h*(t+t/(t+one));
	}

    /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */
	if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7))
		return h*__ieee754_expl(fabsl(x));

    /* |x| in [log(maxdouble), overflowthreshold] */
	if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0
					   || (i0 == 0xb174ddc0
					       && i1 <= 0x31aec0ea)))) {
	    w = __ieee754_expl(0.5*fabsl(x));
	    t = h*w;
	    return t*w;
	}

    /* |x| > overflowthreshold, sinhl(x) overflow */
	return x*shuge;
}
int
__fpclassifyl (long double x)
{
  u_int32_t ex, hx, lx;
  int retval = FP_NORMAL;

  GET_LDOUBLE_WORDS (ex, hx, lx, x);
  ex &= 0x7fff;
  if ((ex | hx | lx) == 0)
    retval = FP_ZERO;
  else if (ex == 0 && (hx & 0x80000000) == 0)
    retval = FP_SUBNORMAL;
  else if (ex == 0x7fff)
    retval = ((hx & 0x7fffffff) | lx) != 0 ? FP_NAN : FP_INFINITE;

  return retval;
}
示例#13
0
long double __frexpl(long double x, int *eptr)
{
	u_int32_t se, hx, ix, lx;
	GET_LDOUBLE_WORDS(se,hx,lx,x);
	ix = 0x7fff&se;
	*eptr = 0;
	if(ix==0x7fff||((ix|hx|lx)==0)) return x + x;	/* 0,inf,nan */
	if (ix==0x0000) {		/* subnormal */
	    x *= two65;
	    GET_LDOUBLE_EXP(se,x);
	    ix = se&0x7fff;
	    *eptr = -65;
	}
	*eptr += ix-16382;
	se = (se & 0x8000) | 0x3ffe;
	SET_LDOUBLE_EXP(x,se);
	return x;
}
示例#14
0
long double
coshl(long double x)
{
	long double t,w;
	int32_t ex;
	u_int32_t mx,lx;

    /* High word of |x|. */
	GET_LDOUBLE_WORDS(ex,mx,lx,x);
	ex &= 0x7fff;

    /* x is INF or NaN */
	if(ex==0x7fff) return x*x;

    /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expl(|x|)) */
	if(ex < 0x3ffd || (ex == 0x3ffd && mx < 0xb17217f7u)) {
	    t = expm1l(fabsl(x));
	    w = one+t;
	    if (ex<0x3fbc) 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 (ex < 0x4003 || (ex == 0x4003 && mx < 0xb0000000u)) {
		t = expl(fabsl(x));
		return half*t+half/t;
	}

    /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */
	if (ex < 0x400c || (ex == 0x400c && mx < 0xb1700000u))
		return half*expl(fabsl(x));

    /* |x| in [log(maxdouble), log(2*maxdouble)) */
	if (ex == 0x400c && (mx < 0xb174ddc0u
			     || (mx == 0xb174ddc0u && lx < 0x31aec0ebu)))
	{
	    w = expl(half*fabsl(x));
	    t = half*w;
	    return t*w;
	}

    /* |x| >= log(2*maxdouble), cosh(x) overflow */
	return huge*huge;
}
示例#15
0
int
__issignalingl (long double x)
{
  u_int32_t exi, hxi, lxi;
  GET_LDOUBLE_WORDS (exi, hxi, lxi, x);
#ifdef HIGH_ORDER_BIT_IS_SET_FOR_SNAN
# error not implemented
#else
  /* 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 ^= 0x40000000;
  /* If lxi != 0, then set any suitable bit of the significand in hxi.  */
  hxi |= (lxi | -lxi) >> 31;
  /* We do not recognize a pseudo NaN as sNaN; they're invalid on 80387 and
     later.  */
  /* We have to compare for greater (instead of greater or equal), because x's
     significand being all-zero designates infinity not NaN.  */
  return ((exi & 0x7fff) == 0x7fff) && (hxi > 0xc0000000);
#endif
}
示例#16
0
文件: s_logbl.c 项目: AubrCool/glibc
long double
__logbl (long double x)
{
  int32_t es, lx, ix;

  GET_LDOUBLE_WORDS (es, ix, lx, x);
  es &= 0x7fff;			/* exponent */
  if ((es | ix | lx) == 0)
    return -1.0 / fabsl (x);
  if (es == 0x7fff)
    return x * x;
  if (es == 0)			/* IEEE 754 logb */
    {
      /* POSIX specifies that denormal number is treated as
         though it were normalized.  */
      if (ix == 0)
	es = -(__builtin_clz (lx) + 32);
      else
	es = -__builtin_clz (ix);
    }
  return (long double) (es - 16383);
}
示例#17
0
文件: acoshl.c 项目: GregorR/musl
long double acoshl(long double x)
{
	long double t;
	uint32_t se,i0,i1;

	GET_LDOUBLE_WORDS(se, i0, i1, x);
	if (se < 0x3fff || se & 0x8000) {  /* x < 1 */
		return (x-x)/(x-x);
	} else if (se >= 0x401d) {  /* x > 2**30 */
		if (se >= 0x7fff)  /* x is inf or NaN */
			return x+x;
		return logl(x) + ln2;  /* acoshl(huge) = logl(2x) */
	} else if (((se-0x3fff)|i0|i1) == 0) {
		return 0.0;            /* acosh(1) = 0 */
	} else if (se > 0x4000) {  /* x > 2 */
		t = x*x;
		return logl(2.0*x - 1.0/(x + sqrtl(t - 1.0)));
	}
	/* 1 < x <= 2 */
	t = x - 1.0;
	return log1pl(t + sqrtl(2.0*t + t*t));
}
示例#18
0
long double
truncl(long double x)
{
	int e, es;
	uint32_t ix0, ix1;

	GET_LDOUBLE_WORDS(es,ix0,ix1,x);
	e = (es&0x7fff) - LDBL_MAX_EXP + 1;

	if (e < MANH_SIZE - 1) {
		if (e < 0) {			/* raise inexact if x != 0 */
			if (huge + x > 0.0)
				return (zero[(es&0x8000)!=0]);
		} else {
			uint64_t m = ((1llu << MANH_SIZE) - 1) >> (e + 1);
			if (((ix0 & m) | ix1) == 0)
				return (x);	/* x is integral */
			if (huge + x > 0.0) {	/* raise inexact flag */
				ix0 &= ~m;
				ix1 = 0;
			}
		}
	} else if (e < LDBL_MANT_DIG - 1) {
示例#19
0
文件: s_modfl.c 项目: AubrCool/glibc
long double
__modfl(long double x, long double *iptr)
{
	int32_t i0,i1,j0;
	u_int32_t i,se;
	GET_LDOUBLE_WORDS(se,i0,i1,x);
	j0 = (se&0x7fff)-0x3fff;	/* exponent of x */
	if(j0<32) {			/* integer part in high x */
	    if(j0<0) {			/* |x|<1 */
		SET_LDOUBLE_WORDS(*iptr,se&0x8000,0,0);	/* *iptr = +-0 */
		return x;
	    } else {
		i = (0x7fffffff)>>j0;
		if(((i0&i)|i1)==0) {		/* x is integral */
		    *iptr = x;
		    SET_LDOUBLE_WORDS(x,se&0x8000,0,0);	/* return +-0 */
		    return x;
		} else {
		    SET_LDOUBLE_WORDS(*iptr,se,i0&(~i),0);
		    return x - *iptr;
		}
	    }
	} else if (__builtin_expect(j0>63, 0)) { /* no fraction part */
示例#20
0
long double __nextafterl(long double x, long double y)
{
	u_int32_t hx,hy,ix,iy;
	u_int32_t lx,ly;
	int32_t esx,esy;

	GET_LDOUBLE_WORDS(esx,hx,lx,x);
	GET_LDOUBLE_WORDS(esy,hy,ly,y);
	ix = esx&0x7fff;		/* |x| */
	iy = esy&0x7fff;		/* |y| */

	/* Intel's extended format has the normally implicit 1 explicit
	   present.  Sigh!  */
	if(((ix==0x7fff)&&(((hx&0x7fffffff)|lx)!=0)) ||   /* x is nan */
	   ((iy==0x7fff)&&(((hy&0x7fffffff)|ly)!=0)))     /* y is nan */
	   return x+y;
	if(x==y) return y;		/* x=y, return y */
	if((ix|hx|lx)==0) {			/* x == 0 */
	    long double u;
	    SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
	    u = math_opt_barrier (x);
	    u = u * u;
	    math_force_eval (u);		/* raise underflow flag */
	    return x;
	}
	if(esx>=0) {			/* x > 0 */
	    if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
	      /* x > y, x -= ulp */
		if(lx==0) {
		    if (hx <= 0x80000000) {
		      if (esx == 0) {
			--hx;
		      } else {
			esx -= 1;
			hx = hx - 1;
			if (esx > 0)
			  hx |= 0x80000000;
		      }
		    } else
		      hx -= 1;
		}
		lx -= 1;
	    } else {				/* x < y, x += ulp */
		lx += 1;
		if(lx==0) {
		    hx += 1;
		    if (hx==0 || (esx == 0 && hx == 0x80000000)) {
			esx += 1;
			hx |= 0x80000000;
		    }
		}
	    }
	} else {				/* x < 0 */
	    if(esy>=0||(esx>esy||((esx==esy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
	      /* x < y, x -= ulp */
		if(lx==0) {
		    if (hx <= 0x80000000 && esx != 0xffff8000) {
			esx -= 1;
			hx = hx - 1;
			if ((esx&0x7fff) > 0)
			  hx |= 0x80000000;
		    } else
		      hx -= 1;
		}
		lx -= 1;
	    } else {				/* x > y, x += ulp */
		lx += 1;
		if(lx==0) {
		    hx += 1;
		    if (hx==0 || (esx == 0xffff8000 && hx == 0x80000000)) {
			esx += 1;
			hx |= 0x80000000;
		    }
		}
	    }
	}
	esy = esx&0x7fff;
	if(esy==0x7fff) {
	    long double u = x + x;	/* overflow  */
	    math_force_eval (u);
	    __set_errno (ERANGE);
	}
	if(esy==0) {
	    long double u = x*x;		/* underflow */
	    math_force_eval (u);		/* raise underflow flag */
	    __set_errno (ERANGE);
	}
	SET_LDOUBLE_WORDS(x,esx,hx,lx);
	return x;
}
示例#21
0
long double
__ieee754_gammal_r (long double x, int *signgamp)
{
  u_int32_t es, hx, lx;

  GET_LDOUBLE_WORDS (es, hx, lx, x);

  if (__glibc_unlikely (((es & 0x7fff) | hx | lx) == 0))
    {
      /* Return value for x == 0 is Inf with divide by zero exception.  */
      *signgamp = 0;
      return 1.0 / x;
    }
  if (__glibc_unlikely (es == 0xffffffff && ((hx & 0x7fffffff) | lx) == 0))
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }
  if (__glibc_unlikely ((es & 0x7fff) == 0x7fff))
    {
      /* Positive infinity (return positive infinity) or NaN (return
	 NaN).  */
      *signgamp = 0;
      return x + x;
    }
  if (__builtin_expect ((es & 0x8000) != 0, 0) && __rintl (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }

  if (x >= 1756.0L)
    {
      /* Overflow.  */
      *signgamp = 0;
      return LDBL_MAX * LDBL_MAX;
    }
  else if (x > 0.0L)
    {
      *signgamp = 0;
      int exp2_adj;
      long double ret = gammal_positive (x, &exp2_adj);
      return __scalbnl (ret, exp2_adj);
    }
  else if (x >= -LDBL_EPSILON / 4.0L)
    {
      *signgamp = 0;
      return 1.0f / x;
    }
  else
    {
      long double tx = __truncl (x);
      *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
      if (x <= -1766.0L)
	/* Underflow.  */
	return LDBL_MIN * LDBL_MIN;
      long double frac = tx - x;
      if (frac > 0.5L)
	frac = 1.0L - frac;
      long double sinpix = (frac <= 0.25L
			    ? __sinl (M_PIl * frac)
			    : __cosl (M_PIl * (0.5L - frac)));
      int exp2_adj;
      long double ret = M_PIl / (-x * sinpix
				 * gammal_positive (-x, &exp2_adj));
      return __scalbnl (ret, -exp2_adj);
    }
}
示例#22
0
long double __nextafterl(long double x, long double y)
{
	int32_t ix,iy,esx,esy;
	uint32_t hx,hy,lx,ly;

	GET_LDOUBLE_WORDS(esx,hx,lx,x);
	GET_LDOUBLE_WORDS(esy,hy,ly,y);
	ix = esx&0x7fff;		/* |x| */
	iy = esy&0x7fff;		/* |y| */

	if(((ix==0x7fff)&&((hx&0x7fffffff)|lx)!=0) ||   /* x is nan */
	   ((iy==0x7fff)&&((hy&0x7fffffff)|ly)!=0))     /* y is nan */
	   return x+y;
	if(x==y) return y;		/* x=y, return y */
	if((ix|hx|lx)==0) {			/* x == 0 */
	    SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
	    y = x*x;
	    math_force_eval (y);		/* raise underflow flag */
	    return x;
	}
	if(esx>=0) {			/* x > 0 */
	    if(esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
	      /* x > y, x -= ulp */
		if(lx==0) {
		    if (ix != 0 && hx == 0x80000000) hx = 0;
		    if (hx==0) esx -= 1;
		    hx -= 1;
		}
		lx -= 1;
	    } else {				/* x < y, x += ulp */
		lx += 1;
		if(lx==0) {
		    hx += 1;
		    if (hx==0) {
			hx = 0x80000000;
			esx += 1;
		    }
		}
	    }
	} else {				/* x < 0 */
	    if(esy>=0||esx>esy||((esx==esy) && (hx>hy||((hx==hy)&&(lx>ly))))){
	      /* x < y, x -= ulp */
		if(lx==0) {
		    if (ix != 0 && hx == 0x80000000) hx = 0;
		    if (hx==0) esx -= 1;
		    hx -= 1;
		}
		lx -= 1;
	    } else {				/* x > y, x += ulp */
		lx += 1;
		if(lx==0) {
		    hx += 1;
		    if (hx==0) {
			hx = 0x80000000;
			esx += 1;
		    }
		}
	    }
	}
	esy = esx&0x7fff;
	if(esy==0x7fff) {
	    long double u = x + x;	/* overflow  */
	    math_force_eval (u);
	    __set_errno (ERANGE);
	}
	if(esy==0 && (hx & 0x80000000) == 0) { /* underflow */
	    y = x*x;
	    math_force_eval (y);		/* raise underflow flag */
	    __set_errno (ERANGE);
	}
	SET_LDOUBLE_WORDS(x,esx,hx,lx);
	return x;
}
示例#23
0
long double
__roundevenl (long double x)
{
  uint16_t se;
  uint32_t hx, lx;
  GET_LDOUBLE_WORDS (se, hx, lx, x);
  int exponent = se & 0x7fff;
  if (exponent >= BIAS + MANT_DIG - 1)
    {
      /* Integer, infinity or NaN.  */
      if (exponent == MAX_EXP)
	/* Infinity or NaN; quiet signaling NaNs.  */
	return x + x;
      else
	return x;
    }
  else if (exponent >= BIAS + MANT_DIG - 32)
    {
      /* Not necessarily an integer; integer bit is in low word.
	 Locate the bits with exponents 0 and -1.  */
      int int_pos = (BIAS + MANT_DIG - 1) - exponent;
      int half_pos = int_pos - 1;
      uint32_t half_bit = 1U << half_pos;
      uint32_t int_bit = 1U << int_pos;
      if ((lx & (int_bit | (half_bit - 1))) != 0)
	{
	  /* No need to test whether HALF_BIT is set.  */
	  lx += half_bit;
	  if (lx < half_bit)
	    {
	      hx++;
	      if (hx == 0)
		{
		  hx = 0x80000000;
		  se++;
		}
	    }
	}
      lx &= ~(int_bit - 1);
    }
  else if (exponent == BIAS + MANT_DIG - 33)
    {
      /* Not necessarily an integer; integer bit is bottom of high
	 word, half bit is top of low word.  */
      if (((hx & 1) | (lx & 0x7fffffff)) != 0)
	{
	  lx += 0x80000000;
	  if (lx < 0x80000000)
	    {
	      hx++;
	      if (hx == 0)
		{
		  hx = 0x80000000;
		  se++;
		}
	    }
	}
      lx = 0;
    }
  else if (exponent >= BIAS)
    {
      /* At least 1; not necessarily an integer, integer bit and half
	 bit are in the high word.  Locate the bits with exponents 0
	 and -1.  */
      int int_pos = (BIAS + MANT_DIG - 33) - exponent;
      int half_pos = int_pos - 1;
      uint32_t half_bit = 1U << half_pos;
      uint32_t int_bit = 1U << int_pos;
      if (((hx & (int_bit | (half_bit - 1))) | lx) != 0)
	{
	  hx += half_bit;
	  if (hx < half_bit)
	    {
	      hx = 0x80000000;
	      se++;
	    }
	}
      hx &= ~(int_bit - 1);
      lx = 0;
    }
  else if (exponent == BIAS - 1 && (hx > 0x80000000 || lx != 0))
    {
      /* Interval (0.5, 1).  */
      se = (se & 0x8000) | 0x3fff;
      hx = 0x80000000;
      lx = 0;
    }
  else
    {
      /* Rounds to 0.  */
      se &= 0x8000;
      hx = 0;
      lx = 0;
    }
  SET_LDOUBLE_WORDS (x, se, hx, lx);
  return x;
}
示例#24
0
long double
nextafterl(long double x, long double y)
{
	int32_t hx,hy,ix,iy;
	u_int32_t lx,ly,esx,esy;

	GET_LDOUBLE_WORDS(esx,hx,lx,x);
	GET_LDOUBLE_WORDS(esy,hy,ly,y);
	ix = esx&0x7fff;		/* |x| */
	iy = esy&0x7fff;		/* |y| */

	if (((ix==0x7fff)&&((hx&0x7fffffff|lx)!=0)) ||   /* x is nan */
	    ((iy==0x7fff)&&((hy&0x7fffffff|ly)!=0)))     /* y is nan */
	   return x+y;
	if(x==y) return y;		/* x=y, return y */
	if((ix|hx|lx)==0) {			/* x == 0 */
	    volatile long double u;
	    SET_LDOUBLE_WORDS(x,esy&0x8000,0,1);/* return +-minsubnormal */
	    u = x;
	    u = u * u;				/* raise underflow flag */
	    return x;
	}
	if(esx<0x8000) {			/* x > 0 */
	    if(ix>iy||((ix==iy) && (hx>hy||((hx==hy)&&(lx>ly))))) {
	      /* x > y, x -= ulp */
		if(lx==0) {
		    if ((hx&0x7fffffff)==0) esx -= 1;
		    hx = (hx - 1) | (hx & 0x80000000);
		}
		lx -= 1;
	    } else {				/* x < y, x += ulp */
		lx += 1;
		if(lx==0) {
		    hx = (hx + 1) | (hx & 0x80000000);
		    if ((hx&0x7fffffff)==0) esx += 1;
		}
	    }
	} else {				/* x < 0 */
	    if(esy>=0||(ix>iy||((ix==iy)&&(hx>hy||((hx==hy)&&(lx>ly)))))){
	      /* x < y, x -= ulp */
		if(lx==0) {
		    if ((hx&0x7fffffff)==0) esx -= 1;
		    hx = (hx - 1) | (hx & 0x80000000);
		}
		lx -= 1;
	    } else {				/* x > y, x += ulp */
		lx += 1;
		if(lx==0) {
		    hx = (hx + 1) | (hx & 0x80000000);
		    if ((hx&0x7fffffff)==0) esx += 1;
		}
	    }
	}
	esy = esx&0x7fff;
	if(esy==0x7fff) return x+x;		/* overflow  */
	if(esy==0) {
	    volatile long double u = x*x;	/* underflow */
	    if(u==x) {
		SET_LDOUBLE_WORDS(x,esx,hx,lx);
		return x;
	    }
	}
	SET_LDOUBLE_WORDS(x,esx,hx,lx);
	return x;
}
示例#25
0
long double __ieee754_hypotl(long double x, long double y)
{
	long double a,b,t1,t2,y1,y2,w;
	u_int32_t j,k,ea,eb;

	GET_LDOUBLE_EXP(ea,x);
	ea &= 0x7fff;
	GET_LDOUBLE_EXP(eb,y);
	eb &= 0x7fff;
	if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;}
	SET_LDOUBLE_EXP(a,ea);	/* a <- |a| */
	SET_LDOUBLE_EXP(b,eb);	/* b <- |b| */
	if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */
	k=0;
	if(__builtin_expect(ea > 0x5f3f,0)) {	/* a>2**8000 */
	   if(ea == 0x7fff) {	/* Inf or NaN */
	       u_int32_t exp __attribute__ ((unused));
	       u_int32_t high,low;
	       w = a+b;			/* for sNaN */
	       GET_LDOUBLE_WORDS(exp,high,low,a);
	       if(((high&0x7fffffff)|low)==0) w = a;
	       GET_LDOUBLE_WORDS(exp,high,low,b);
	       if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b;
	       return w;
	   }
	   /* scale a and b by 2**-9600 */
	   ea -= 0x2580; eb -= 0x2580;	k += 9600;
	   SET_LDOUBLE_EXP(a,ea);
	   SET_LDOUBLE_EXP(b,eb);
	}
	if(__builtin_expect(eb < 0x20bf, 0)) {	/* b < 2**-8000 */
	    if(eb == 0) {	/* subnormal b or 0 */
		u_int32_t exp __attribute__ ((unused));
		u_int32_t high,low;
		GET_LDOUBLE_WORDS(exp,high,low,b);
		if((high|low)==0) return a;
		SET_LDOUBLE_WORDS(t1, 0x7ffd, 0x80000000, 0); /* t1=2^16382 */
		b *= t1;
		a *= t1;
		k -= 16382;
		GET_LDOUBLE_EXP (ea, a);
		GET_LDOUBLE_EXP (eb, b);
		if (eb > ea)
		  {
		    t1 = a;
		    a = b;
		    b = t1;
		    j = ea;
		    ea = eb;
		    eb = j;
		  }
	    } else {		/* scale a and b by 2^9600 */
		ea += 0x2580;	/* a *= 2^9600 */
		eb += 0x2580;	/* b *= 2^9600 */
		k -= 9600;
		SET_LDOUBLE_EXP(a,ea);
		SET_LDOUBLE_EXP(b,eb);
	    }
	}
    /* medium size a and b */
	w = a-b;
	if (w>b) {
	    u_int32_t high;
	    GET_LDOUBLE_MSW(high,a);
	    SET_LDOUBLE_WORDS(t1,ea,high,0);
	    t2 = a-t1;
	    w  = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
	} else {
	    u_int32_t high;
	    GET_LDOUBLE_MSW(high,b);
	    a  = a+a;
	    SET_LDOUBLE_WORDS(y1,eb,high,0);
	    y2 = b - y1;
	    GET_LDOUBLE_MSW(high,a);
	    SET_LDOUBLE_WORDS(t1,ea+1,high,0);
	    t2 = a - t1;
	    w  = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b)));
	}
	if(k!=0) {
	    u_int32_t exp;
	    t1 = 1.0;
	    GET_LDOUBLE_EXP(exp,t1);
	    SET_LDOUBLE_EXP(t1,exp+k);
	    w *= t1;
	    math_check_force_underflow_nonneg (w);
	    return w;
	} else return w;
}
示例#26
0
long double
hypotl(long double x, long double y)
{
	long double a,b,t1,t2,yy1,y2,w;
	u_int32_t j,k,ea,eb;

	GET_LDOUBLE_EXP(ea,x);
	ea &= 0x7fff;
	GET_LDOUBLE_EXP(eb,y);
	eb &= 0x7fff;
	if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;}
	SET_LDOUBLE_EXP(a,ea);	/* a <- |a| */
	SET_LDOUBLE_EXP(b,eb);	/* b <- |b| */
	if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */
	k=0;
	if(ea > 0x5f3f) {	/* a>2**8000 */
	   if(ea == 0x7fff) {	/* Inf or NaN */
	       u_int32_t es,high,low;
	       w = a+b;			/* for sNaN */
	       GET_LDOUBLE_WORDS(es,high,low,a);
	       if(((high&0x7fffffff)|low)==0) w = a;
	       GET_LDOUBLE_WORDS(es,high,low,b);
	       if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b;
	       return w;
	   }
	   /* scale a and b by 2**-9600 */
	   ea -= 0x2580; eb -= 0x2580;	k += 9600;
	   SET_LDOUBLE_EXP(a,ea);
	   SET_LDOUBLE_EXP(b,eb);
	}
	if(eb < 0x20bf) {	/* b < 2**-8000 */
	    if(eb == 0) {	/* subnormal b or 0 */
		u_int32_t es,high,low;
		GET_LDOUBLE_WORDS(es,high,low,b);
		if((high|low)==0) return a;
		SET_LDOUBLE_WORDS(t1, 0x7ffd, 0, 0);	/* t1=2^16382 */
		b *= t1;
		a *= t1;
		k -= 16382;
	    } else {		/* scale a and b by 2^9600 */
		ea += 0x2580;	/* a *= 2^9600 */
		eb += 0x2580;	/* b *= 2^9600 */
		k -= 9600;
		SET_LDOUBLE_EXP(a,ea);
		SET_LDOUBLE_EXP(b,eb);
	    }
	}
    /* medium size a and b */
	w = a-b;
	if (w>b) {
	    u_int32_t high;
	    GET_LDOUBLE_MSW(high,a);
	    SET_LDOUBLE_WORDS(t1,ea,high,0);
	    t2 = a-t1;
	    w  = sqrtl(t1*t1-(b*(-b)-t2*(a+t1)));
	} else {
	    u_int32_t high;
	    GET_LDOUBLE_MSW(high,b);
	    a  = a+a;
	    SET_LDOUBLE_WORDS(yy1,eb,high,0);
	    y2 = b - yy1;
	    GET_LDOUBLE_MSW(high,a);
	    SET_LDOUBLE_WORDS(t1,ea+1,high,0);
	    t2 = a - t1;
	    w  = sqrtl(t1*yy1-(w*(-w)-(t1*y2+t2*b)));
	}
	if(k!=0) {
	    u_int32_t es;
	    t1 = 1.0;
	    GET_LDOUBLE_EXP(es,t1);
	    SET_LDOUBLE_EXP(t1,es+k);
	    return t1*w;
	} else return w;
}