コード例 #1
0
ファイル: s_totalorderl.c プロジェクト: kraj/glibc
int
totalorderl (_Float128 x, _Float128 y)
{
    int64_t hx, hy;
    uint64_t lx, ly;
    GET_LDOUBLE_WORDS64 (hx, lx, x);
    GET_LDOUBLE_WORDS64 (hy, ly, y);
#if HIGH_ORDER_BIT_IS_SET_FOR_SNAN
    uint64_t uhx = hx & 0x7fffffffffffffffULL;
    uint64_t uhy = hy & 0x7fffffffffffffffULL;
    /* For the preferred quiet NaN convention, this operation is a
       comparison of the representations of the arguments interpreted as
       sign-magnitude integers.  If both arguments are NaNs, invert the
       quiet/signaling bit so comparing that way works.  */
    if ((uhx > 0x7fff000000000000ULL || (uhx == 0x7fff000000000000ULL
                                         && lx != 0))
            && (uhy > 0x7fff000000000000ULL || (uhy == 0x7fff000000000000ULL
                    && ly != 0)))
    {
        hx ^= 0x0000800000000000ULL;
        hy ^= 0x0000800000000000ULL;
    }
#endif
    uint64_t hx_sign = hx >> 63;
    uint64_t hy_sign = hy >> 63;
    hx ^= hx_sign >> 1;
    lx ^= hx_sign;
    hy ^= hy_sign >> 1;
    ly ^= hy_sign;
    return hx < hy || (hx == hy && lx <= ly);
}
コード例 #2
0
ファイル: s_nextafterl.c プロジェクト: AubrCool/glibc
long double __nextafterl(long double x, long double y)
{
	int64_t hx,hy,ix,iy;
	u_int64_t lx,ly;

	GET_LDOUBLE_WORDS64(hx,lx,x);
	GET_LDOUBLE_WORDS64(hy,ly,y);
	ix = hx&0x7fffffffffffffffLL;		/* |x| */
	iy = hy&0x7fffffffffffffffLL;		/* |y| */

	if(((ix>=0x7fff000000000000LL)&&((ix-0x7fff000000000000LL)|lx)!=0) ||   /* x is nan */
	   ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|ly)!=0))     /* y is nan */
	   return x+y;
	if(x==y) return y;		/* x=y, return y */
	if((ix|lx)==0) {			/* x == 0 */
	    long double u;
	    SET_LDOUBLE_WORDS64(x,hy&0x8000000000000000ULL,1);/* return +-minsubnormal */
	    u = math_opt_barrier (x);
	    u = u * u;
	    math_force_eval (u);		/* raise underflow flag */
	    return x;
	}
	if(hx>=0) {			/* x > 0 */
	    if(hx>hy||((hx==hy)&&(lx>ly))) {	/* x > y, x -= ulp */
		if(lx==0) hx--;
		lx--;
	    } else {				/* x < y, x += ulp */
		lx++;
		if(lx==0) hx++;
	    }
	} else {				/* x < 0 */
	    if(hy>=0||hx>hy||((hx==hy)&&(lx>ly))){/* x < y, x -= ulp */
		if(lx==0) hx--;
		lx--;
	    } else {				/* x > y, x += ulp */
		lx++;
		if(lx==0) hx++;
	    }
	}
	hy = hx&0x7fff000000000000LL;
	if(hy==0x7fff000000000000LL) {
	    long double u = x + x;		/* overflow  */
	    math_force_eval (u);
	}
	if(hy==0) {
	    long double u = x*x;		/* underflow */
	    math_force_eval (u);		/* raise underflow flag */
	}
	SET_LDOUBLE_WORDS64(x,hx,lx);
	return x;
}
コード例 #3
0
ファイル: s_nexttoward.c プロジェクト: apinski-cavium/glibc
double __nexttoward(double x, long double y)
{
	int32_t hx,ix;
	int64_t hy,iy;
	u_int32_t lx;
	u_int64_t ly;

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

	if(((ix>=0x7ff00000)&&((ix-0x7ff00000)|lx)!=0) ||   /* x is nan */
	   ((iy>=0x7fff000000000000LL)&&((iy-0x7fff000000000000LL)|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,(u_int32_t)((hy>>32)&0x80000000),1);/* return +-minsub */
	    u = math_opt_barrier (x);
	    u = u * u;
	    math_force_eval (u);		/* raise underflow flag */
	    return x;
	}
コード例 #4
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.  */
  int64_t hx;
  u_int64_t lx;

  GET_LDOUBLE_WORDS64 (hx, lx, x);

  if (((hx | lx) & 0x7fffffffffffffffLL) == 0)
    {
      /* Return value for x == 0 is Inf with divide by zero exception.  */
      *signgamp = 0;
      return 1.0 / x;
    }
  if (hx < 0 && (u_int64_t) hx < 0xfff0000000000000ULL && __rintl (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }
  if (hx == 0xfff0000000000000ULL)
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }

  /* XXX FIXME.  */
  return __ieee754_expl (__ieee754_lgammal_r (x, signgamp));
}
コード例 #5
0
ファイル: e_atanhl.c プロジェクト: mbref/eglibc-microblaze
long double
__ieee754_atanhl(long double x)
{
    long double t;
    int64_t hx,ix;
    u_int64_t lx __attribute__ ((unused));
    GET_LDOUBLE_WORDS64(hx,lx,x);
    ix = hx&0x7fffffffffffffffLL;
    if (ix >= 0x3ff0000000000000LL) { /* |x|>=1 */
        if (ix > 0x3ff0000000000000LL)
            return (x-x)/(x-x);
        t = fabsl (x);
        if (t > one)
            return (x-x)/(x-x);
        if (t == one)
            return x/zero;
    }
    if(ix<0x3e20000000000000LL&&(huge+x)>zero) return x;	/* x<2**-29 */
    x = fabsl (x);
    if(ix<0x3fe0000000000000LL) {		/* x < 0.5 */
        t = x+x;
        t = 0.5*__log1pl(t+t*x/(one-x));
    } else
        t = 0.5*__log1pl((x+x)/(one-x));
    if(hx>=0) return t;
    else return -t;
}
コード例 #6
0
int
___isnanl (long double x)
{
	int64_t hx,lx;
	GET_LDOUBLE_WORDS64(hx,lx,x);
	hx &= 0x7fffffffffffffffLL;
	hx = 0x7ff0000000000000LL - hx;
	return (int)((u_int64_t)hx>>63);
}
コード例 #7
0
ファイル: s_isnanl.c プロジェクト: mbref/eglibc-microblaze
int
___isnanl (long double x)
{
	int64_t hx;
	int64_t lx __attribute__ ((unused));
	GET_LDOUBLE_WORDS64(hx,lx,x);
	hx &= 0x7fffffffffffffffLL;
	hx = 0x7ff0000000000000LL - hx;
	return (int)((u_int64_t)hx>>63);
}
コード例 #8
0
ファイル: e_remainderl.c プロジェクト: riscv/riscv-glibc
_Float128
__ieee754_remainderl(_Float128 x, _Float128 p)
{
	int64_t hx,hp;
	uint64_t sx,lx,lp;
	_Float128 p_half;

	GET_LDOUBLE_WORDS64(hx,lx,x);
	GET_LDOUBLE_WORDS64(hp,lp,p);
	sx = hx&0x8000000000000000ULL;
	hp &= 0x7fffffffffffffffLL;
	hx &= 0x7fffffffffffffffLL;

    /* purge off exception values */
	if((hp|lp)==0) return (x*p)/(x*p);	/* p = 0 */
	if((hx>=0x7fff000000000000LL)||			/* x not finite */
	  ((hp>=0x7fff000000000000LL)&&			/* p is NaN */
	  (((hp-0x7fff000000000000LL)|lp)!=0)))
	    return (x*p)/(x*p);


	if (hp<=0x7ffdffffffffffffLL) x = __ieee754_fmodl(x,p+p);	/* now x < 2p */
	if (((hx-hp)|(lx-lp))==0) return zero*x;
	x  = fabsl(x);
	p  = fabsl(p);
	if (hp<0x0002000000000000LL) {
	    if(x+x>p) {
		x-=p;
		if(x+x>=p) x -= p;
	    }
	} else {
	    p_half = L(0.5)*p;
	    if(x>p_half) {
		x-=p;
		if(x>=p_half) x -= p;
	    }
	}
	GET_LDOUBLE_MSW64(hx,x);
	SET_LDOUBLE_MSW64(x,hx^sx);
	return x;
}
コード例 #9
0
ファイル: s_fpclassifyl.c プロジェクト: czankel/xtensa-glibc
int
___fpclassifyl (long double x)
{
  u_int64_t hx, lx;
  int retval = FP_NORMAL;

  GET_LDOUBLE_WORDS64 (hx, lx, x);
  if ((hx & 0x7ff0000000000000ULL) == 0x7ff0000000000000ULL) {
      /* +/-NaN or +/-Inf */
      if (hx & 0x000fffffffffffffULL) {
	  /* +/-NaN */
	  retval = FP_NAN;
      } else {
	  retval = FP_INFINITE;
      }
  } else {
      /* +/-zero or +/- normal or +/- denormal */
      if (hx & 0x7fffffffffffffffULL) {
	  /* +/- normal or +/- denormal */
	  if ((hx & 0x7ff0000000000000ULL) > 0x0360000000000000ULL) {
	      /* +/- normal */
	      retval = FP_NORMAL;
	  } else {
	      if ((hx & 0x7ff0000000000000ULL) == 0x0360000000000000ULL) {
		  if ((lx & 0x7fffffffffffffff)	/* lower is non-zero */
		  && ((lx^hx) & 0x8000000000000000ULL)) { /* and sign differs */
		      /* +/- denormal */
		      retval = FP_SUBNORMAL;
		  } else {
		      /* +/- normal */
		      retval = FP_NORMAL;
		  }
	      } else {
		  /* +/- denormal */
		  retval = FP_SUBNORMAL;
	      }
	  }
      } else {
	  /* +/- zero */
	  retval = FP_ZERO;
      }
  }

  return retval;
}
コード例 #10
0
ファイル: s_fpclassifyl.c プロジェクト: JamesLinus/glibc-mips
int
__fpclassifyl (long double x)
{
  u_int64_t hx, lx;
  int retval = FP_NORMAL;

  GET_LDOUBLE_WORDS64 (hx, lx, x);
  lx |= (hx & 0x0000ffffffffffffLL);
  hx &= 0x7fff000000000000LL;
  if ((hx | lx) == 0)
    retval = FP_ZERO;
  else if (hx == 0)
    retval = FP_SUBNORMAL;
  else if (hx == 0x7fff000000000000LL)
    retval = lx != 0 ? FP_NAN : FP_INFINITE;

  return retval;
}
コード例 #11
0
ファイル: s_frexpl.c プロジェクト: riscv/riscv-glibc
_Float128 __frexpl(_Float128 x, int *eptr)
{
	uint64_t hx, lx, ix;
	GET_LDOUBLE_WORDS64(hx,lx,x);
	ix = 0x7fffffffffffffffULL&hx;
	*eptr = 0;
	if(ix>=0x7fff000000000000ULL||((ix|lx)==0)) return x + x;/* 0,inf,nan */
	if (ix<0x0001000000000000ULL) {		/* subnormal */
	    x *= two114;
	    GET_LDOUBLE_MSW64(hx,x);
	    ix = hx&0x7fffffffffffffffULL;
	    *eptr = -114;
	}
	*eptr += (ix>>48)-16382;
	hx = (hx&0x8000ffffffffffffULL) | 0x3ffe000000000000ULL;
	SET_LDOUBLE_MSW64(x,hx);
	return x;
}
コード例 #12
0
ファイル: e_ilogbl.c プロジェクト: AubrCool/glibc
int __ieee754_ilogbl (long double x)
{
	int64_t hx,lx;
	int ix;

	GET_LDOUBLE_WORDS64(hx,lx,x);
	hx &= 0x7fffffffffffffffLL;
	if(hx <= 0x0001000000000000LL) {
	    if((hx|lx)==0)
		return FP_ILOGB0;	/* ilogbl(0) = FP_ILOGB0 */
	    else			/* subnormal x */
		if(hx==0) {
		    for (ix = -16431; lx>0; lx<<=1) ix -=1;
		} else {
		    for (ix = -16382, hx<<=15; hx>0; hx<<=1) ix -=1;
		}
	    return ix;
	}
	else if (hx<0x7fff000000000000LL) return (hx>>48)-0x3fff;
	else if (FP_ILOGBNAN != INT_MAX) {
コード例 #13
0
ファイル: e_acoshl.c プロジェクト: dreal/tai
long double
__ieee754_acoshl(long double x)
{
	long double t;
	u_int64_t lx;
	int64_t hx;
	GET_LDOUBLE_WORDS64(hx,lx,x);
	if(hx<0x3fff000000000000LL) {		/* x < 1 */
	    return (x-x)/(x-x);
	} else if(hx >=0x4035000000000000LL) {	/* x > 2**54 */
	    if(hx >=0x7fff000000000000LL) {	/* x is inf of NaN */
		return x+x;
	    } else
		return __ieee754_logl(x)+ln2;	/* acoshl(huge)=logl(2x) */
	} else if(((hx-0x3fff000000000000LL)|lx)==0) {
	    return 0.0L;			/* acosh(1) = 0 */
	} else if (hx > 0x4000000000000000LL) {	/* 2**28 > x > 2 */
	    t=x*x;
	    return __ieee754_logl(2.0L*x-one/(x+__ieee754_sqrtl(t-one)));
	} else {			/* 1<x<2 */
	    t = x-one;
	    return __log1pl(t+__sqrtl(2.0L*t+t*t));
	}
}
コード例 #14
0
ファイル: s_remquol.c プロジェクト: kraj/glibc
_Float128
__remquol (_Float128 x, _Float128 y, int *quo)
{
  int64_t hx,hy;
  u_int64_t sx,lx,ly,qs;
  int cquo;

  GET_LDOUBLE_WORDS64 (hx, lx, x);
  GET_LDOUBLE_WORDS64 (hy, ly, y);
  sx = hx & 0x8000000000000000ULL;
  qs = sx ^ (hy & 0x8000000000000000ULL);
  hy &= 0x7fffffffffffffffLL;
  hx &= 0x7fffffffffffffffLL;

  /* Purge off exception values.  */
  if ((hy | ly) == 0)
    return (x * y) / (x * y); 			/* y = 0 */
  if ((hx >= 0x7fff000000000000LL)		/* x not finite */
      || ((hy >= 0x7fff000000000000LL)		/* y is NaN */
	  && (((hy - 0x7fff000000000000LL) | ly) != 0)))
    return (x * y) / (x * y);

  if (hy <= 0x7ffbffffffffffffLL)
    x = __ieee754_fmodl (x, 8 * y);              /* now x < 8y */

  if (((hx - hy) | (lx - ly)) == 0)
    {
      *quo = qs ? -1 : 1;
      return zero * x;
    }

  x  = fabsl (x);
  y  = fabsl (y);
  cquo = 0;

  if (hy <= 0x7ffcffffffffffffLL && x >= 4 * y)
    {
      x -= 4 * y;
      cquo += 4;
    }
  if (hy <= 0x7ffdffffffffffffLL && x >= 2 * y)
    {
      x -= 2 * y;
      cquo += 2;
    }

  if (hy < 0x0002000000000000LL)
    {
      if (x + x > y)
	{
	  x -= y;
	  ++cquo;
	  if (x + x >= y)
	    {
	      x -= y;
	      ++cquo;
	    }
	}
    }
  else
    {
      _Float128 y_half = L(0.5) * y;
      if (x > y_half)
	{
	  x -= y;
	  ++cquo;
	  if (x >= y_half)
	    {
	      x -= y;
	      ++cquo;
	    }
	}
    }

  *quo = qs ? -cquo : cquo;

  /* Ensure correct sign of zero result in round-downward mode.  */
  if (x == 0)
    x = 0;
  if (sx)
    x = -x;
  return x;
}
コード例 #15
0
long double __nextafterl(long double x, long double y)
{
	int64_t hx,hy,ihx,ihy,ilx;
	u_int64_t lx,ly;

	GET_LDOUBLE_WORDS64(hx,lx,x);
	GET_LDOUBLE_WORDS64(hy,ly,y);
	ihx = hx&0x7fffffffffffffffLL;		/* |hx| */
	ilx = lx&0x7fffffffffffffffLL;		/* |lx| */
	ihy = hy&0x7fffffffffffffffLL;		/* |hy| */

	if((((ihx&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
	    ((ihx&0x000fffffffffffffLL)!=0)) ||   /* x is nan */
	   (((ihy&0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
	    ((ihy&0x000fffffffffffffLL)!=0)))     /* y is nan */
	    return x+y; /* signal the nan */
	if(x==y)
	    return y;		/* x=y, return y */
	if(ihx == 0 && ilx == 0) {			/* x == 0 */
	    long double u;
	    hy = (hy & 0x8000000000000000ULL) | 1;
	    SET_LDOUBLE_WORDS64(x,hy,0ULL);/* return +-minsubnormal */
	    u = math_opt_barrier (x);
	    u = u * u;
	    math_force_eval (u);		/* raise underflow flag */
	    return x;
	}
	
	long double u;
	if(x > y) {	/* x > y, x -= ulp */
	    if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL))
	      return x+x;	/* overflow, return -inf */
	    if (hx >= 0x7ff0000000000000LL) {
	      SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL);
	      return u;
	    }
	    if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
	      u = math_opt_barrier (x);
	      x -= __LDBL_DENORM_MIN__;
	      if (ihx < 0x0360000000000000LL
		  || (hx > 0 && (int64_t) lx <= 0)
		  || (hx < 0 && (int64_t) lx > 1)) {
		u = u * u;
		math_force_eval (u);		/* raise underflow flag */
	      }
	      return x;
	    }
	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
	      u *= 0x1.0000000000000p-105L;
	    } else
	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
	    return x - u;
	} else {				/* x < y, x += ulp */
	    if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL))
	      return x+x;	/* overflow, return +inf */
	    if ((u_int64_t) hx >= 0xfff0000000000000ULL) {
	      SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL);
	      return u;
	    }
	    if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
	      u = math_opt_barrier (x);
	      x += __LDBL_DENORM_MIN__;
	      if (ihx < 0x0360000000000000LL
		  || (hx > 0 && (int64_t) lx < 0 && lx != 0x8000000000000001LL)
		  || (hx < 0 && (int64_t) lx >= 0)) {
		u = u * u;
		math_force_eval (u);		/* raise underflow flag */
	      }
	      if (x == 0.0L)	/* handle negative __LDBL_DENORM_MIN__ case */
		x = -0.0L;
	      return x;
	    }
	    if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
	      u *= 0x1.0000000000000p-105L;
	    } else
	      SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
	    return x + u;
	}
}
コード例 #16
0
ファイル: e_gammal_r.c プロジェクト: KubaKaszycki/kklibc
long double
__ieee754_gammal_r (long double x, int *signgamp)
{
  int64_t hx;
  u_int64_t lx;
  long double ret;

  GET_LDOUBLE_WORDS64 (hx, lx, x);

  if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
    {
      /* Return value for x == 0 is Inf with divide by zero exception.  */
      *signgamp = 0;
      return 1.0 / x;
    }
  if (hx < 0 && (u_int64_t) hx < 0xffff000000000000ULL && __rintl (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }
  if (hx == 0xffff000000000000ULL && lx == 0)
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }
  if ((hx & 0x7fff000000000000ULL) == 0x7fff000000000000ULL)
    {
      /* Positive infinity (return positive infinity) or NaN (return
	 NaN).  */
      *signgamp = 0;
      return x + x;
    }

  if (x >= 1756.0L)
    {
      /* Overflow.  */
      *signgamp = 0;
      return LDBL_MAX * LDBL_MAX;
    }
  else
    {
      SET_RESTORE_ROUNDL (FE_TONEAREST);
      if (x > 0.0L)
	{
	  *signgamp = 0;
	  int exp2_adj;
	  ret = gammal_positive (x, &exp2_adj);
	  ret = __scalbnl (ret, exp2_adj);
	}
      else if (x >= -LDBL_EPSILON / 4.0L)
	{
	  *signgamp = 0;
	  ret = 1.0L / x;
	}
      else
	{
	  long double tx = __truncl (x);
	  *signgamp = (tx == 2.0L * __truncl (tx / 2.0L)) ? -1 : 1;
	  if (x <= -1775.0L)
	    /* Underflow.  */
	    ret = LDBL_MIN * LDBL_MIN;
	  else
	    {
	      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;
	      ret = M_PIl / (-x * sinpix
			     * gammal_positive (-x, &exp2_adj));
	      ret = __scalbnl (ret, -exp2_adj);
	    }
	}
    }
  if (isinf (ret) && x != 0)
    {
      if (*signgamp < 0)
	return -(-__copysignl (LDBL_MAX, ret) * LDBL_MAX);
      else
	return __copysignl (LDBL_MAX, ret) * LDBL_MAX;
    }
  else if (ret == 0)
    {
      if (*signgamp < 0)
	return -(-__copysignl (LDBL_MIN, ret) * LDBL_MIN);
      else
	return __copysignl (LDBL_MIN, ret) * LDBL_MIN;
    }
  else
    return ret;
}
コード例 #17
0
ファイル: s_remquol.c プロジェクト: Drakey83/steamlink-sdk
long double
__remquol (long double x, long double y, int *quo)
{
  int64_t hx,hy;
  u_int64_t sx,lx,ly,qs;
  int cquo;

  GET_LDOUBLE_WORDS64 (hx, lx, x);
  GET_LDOUBLE_WORDS64 (hy, ly, y);
  sx = hx & 0x8000000000000000ULL;
  qs = sx ^ (hy & 0x8000000000000000ULL);
  hy &= 0x7fffffffffffffffLL;
  hx &= 0x7fffffffffffffffLL;

  /* Purge off exception values.  */
  if ((hy | ly) == 0)
    return (x * y) / (x * y); 			/* y = 0 */
  if ((hx >= 0x7fff000000000000LL)		/* x not finite */
      || ((hy >= 0x7fff000000000000LL)		/* y is NaN */
	  && (((hy - 0x7fff000000000000LL) | ly) != 0)))
    return (x * y) / (x * y);

  if (hy <= 0x7ffbffffffffffffLL)
    x = __ieee754_fmodl (x, 8 * y);              /* now x < 8y */

  if (((hx - hy) | (lx - ly)) == 0)
    {
      *quo = qs ? -1 : 1;
      return zero * x;
    }

  x  = fabsl (x);
  y  = fabsl (y);
  cquo = 0;

  if (x >= 4 * y)
    {
      x -= 4 * y;
      cquo += 4;
    }
  if (x >= 2 * y)
    {
      x -= 2 * y;
      cquo += 2;
    }

  if (hy < 0x0002000000000000LL)
    {
      if (x + x > y)
	{
	  x -= y;
	  ++cquo;
	  if (x + x >= y)
	    {
	      x -= y;
	      ++cquo;
	    }
	}
    }
  else
    {
      long double y_half = 0.5L * y;
      if (x > y_half)
	{
	  x -= y;
	  ++cquo;
	  if (x >= y_half)
	    {
	      x -= y;
	      ++cquo;
	    }
	}
    }

  *quo = qs ? -cquo : cquo;

  if (sx)
    x = -x;
  return x;
}
コード例 #18
0
ファイル: e_log10l.c プロジェクト: michalsc/AROS
long double
log10l(long double x)
{
  long double z;
  long double y;
  int e;
  int64_t hx, lx;

/* Test for domain */
  GET_LDOUBLE_WORDS64 (hx, lx, x);
  if (((hx & 0x7fffffffffffffffLL) | lx) == 0)
    return (-1.0L / (x - x));
  if (hx < 0)
    return (x - x) / (x - x);
  if (hx >= 0x7fff000000000000LL)
    return (x + x);

/* separate mantissa from exponent */

/* Note, frexp is used so that denormal numbers
 * will be handled properly.
 */
  x = frexpl (x, &e);


/* logarithm using log(x) = z + z**3 P(z)/Q(z),
 * where z = 2(x-1)/x+1)
 */
  if ((e > 2) || (e < -2))
    {
      if (x < SQRTH)
	{			/* 2( 2x-1 )/( 2x+1 ) */
	  e -= 1;
	  z = x - 0.5L;
	  y = 0.5L * z + 0.5L;
	}
      else
	{			/*  2 (x-1)/(x+1)   */
	  z = x - 0.5L;
	  z -= 0.5L;
	  y = 0.5L * x + 0.5L;
	}
      x = z / y;
      z = x * x;
      y = x * (z * neval (z, R, 5) / deval (z, S, 5));
      goto done;
    }


/* logarithm using log(1+x) = x - .5x**2 + x**3 P(x)/Q(x) */

  if (x < SQRTH)
    {
      e -= 1;
      x = 2.0 * x - 1.0L;	/*  2x - 1  */
    }
  else
    {
      x = x - 1.0L;
    }
  z = x * x;
  y = x * (z * neval (x, P, 12) / deval (x, Q, 11));
  y = y - 0.5 * z;

done:

  /* Multiply log of fraction by log10(e)
   * and base 2 exponent by log10(2).
   */
  z = y * L10EB;
  z += x * L10EB;
  z += e * L102B;
  z += y * L10EA;
  z += x * L10EA;
  z += e * L102A;
  return (z);
}
コード例 #19
0
npy_longdouble _nextl(npy_longdouble x, int p)
{
    npy_int64 hx,ihx,ilx;
    npy_uint64 lx;

    GET_LDOUBLE_WORDS64(hx, lx, x);
    ihx = hx & 0x7fffffffffffffffLL;      /* |hx| */
    ilx = lx & 0x7fffffffffffffffLL;      /* |lx| */

    if(((ihx & 0x7ff0000000000000LL)==0x7ff0000000000000LL)&&
       ((ihx & 0x000fffffffffffffLL)!=0)) {
        return x; /* signal the nan */
    }
    if(ihx == 0 && ilx == 0) {          /* x == 0 */
        npy_longdouble u;
        SET_LDOUBLE_WORDS64(x, p, 0ULL);/* return +-minsubnormal */
        u = x * x;
        if (u == x) {
            return u;
        } else {
            return x;           /* raise underflow flag */
        }
    }

    npy_longdouble u;
    if(p < 0) { /* p < 0, x -= ulp */
        if((hx==0xffefffffffffffffLL)&&(lx==0xfc8ffffffffffffeLL))
            return x+x; /* overflow, return -inf */
        if (hx >= 0x7ff0000000000000LL) {
            SET_LDOUBLE_WORDS64(u,0x7fefffffffffffffLL,0x7c8ffffffffffffeLL);
            return u;
        }
        if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
            u = math_opt_barrier (x);
            x -= LDBL_TRUE_MIN;
            if (ihx < 0x0360000000000000LL
                    || (hx > 0 && (npy_int64) lx <= 0)
                    || (hx < 0 && (npy_int64) lx > 1)) {
                u = u * u;
                math_force_eval (u);        /* raise underflow flag */
            }
            return x;
        }
        if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
            SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
            u *= 0x1.0000000000000p-105L;
        } else
            SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
        return x - u;
    } else {                /* p >= 0, x += ulp */
        if((hx==0x7fefffffffffffffLL)&&(lx==0x7c8ffffffffffffeLL))
            return x+x; /* overflow, return +inf */
        if ((npy_uint64) hx >= 0xfff0000000000000ULL) {
            SET_LDOUBLE_WORDS64(u,0xffefffffffffffffLL,0xfc8ffffffffffffeLL);
            return u;
        }
        if(ihx <= 0x0360000000000000LL) {  /* x <= LDBL_MIN */
            u = math_opt_barrier (x);
            x += LDBL_TRUE_MIN;
            if (ihx < 0x0360000000000000LL
                    || (hx > 0 && (npy_int64) lx < 0 && lx != 0x8000000000000001LL)
                    || (hx < 0 && (npy_int64) lx >= 0)) {
                u = u * u;
                math_force_eval (u);        /* raise underflow flag */
            }
            if (x == 0.0L)  /* handle negative LDBL_TRUE_MIN case */
                x = -0.0L;
            return x;
        }
        if (ihx < 0x06a0000000000000LL) { /* ulp will denormal */
            SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL),0ULL);
            u *= 0x1.0000000000000p-105L;
        } else
            SET_LDOUBLE_WORDS64(u,(hx&0x7ff0000000000000LL)-0x0690000000000000LL,0ULL);
        return x + u;
    }
}