Example #1
0
float
__ieee754_atanhf (float x)
{
  float xa = fabsf (x);
  float t;
  if (isless (xa, 0.5f))
    {
      if (__glibc_unlikely (xa < 0x1.0p-28f))
	{
	  math_force_eval (huge + x);
	  math_check_force_underflow (x);
	  return x;
	}

      t = xa + xa;
      t = 0.5f * __log1pf (t + t * xa / (1.0f - xa));
    }
  else if (__glibc_likely (isless (xa, 1.0f)))
    t = 0.5f * __log1pf ((xa + xa) / (1.0f - xa));
  else
    {
      if (isgreater (xa, 1.0f))
	return (x - x) / (x - x);

      return x / 0.0f;
    }

  return __copysignf (t, x);
}
Example #2
0
double
__asinh (double x)
{
  double w;
  int32_t hx, ix;
  GET_HIGH_WORD (hx, x);
  ix = hx & 0x7fffffff;
  if (__glibc_unlikely (ix < 0x3e300000))                  /* |x|<2**-28 */
    {
      math_check_force_underflow (x);
      if (huge + x > one)
	return x;                       /* return x inexact except 0 */
    }
  if (__glibc_unlikely (ix > 0x41b00000))                  /* |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 / (sqrt (xa * xa + one) +
              xa));
	}
      else                      /* 2.0 > |x| > 2**-28 */
	{
	  double t = xa * xa;
	  w = __log1p (xa + t / (one + sqrt (one + t)));
	}
    }
  return copysign (w, x);
}
Example #3
0
float
__asinhf(float x)
{
	float w;
	int32_t hx,ix;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(__builtin_expect(ix< 0x38000000, 0)) {	/* |x|<2**-14 */
	    math_check_force_underflow (x);
	    if(huge+x>one) return x;	/* return x inexact except 0 */
	}
	if(__builtin_expect(ix>0x47000000, 0)) {	/* |x| > 2**14 */
	    if(ix>=0x7f800000) return x+x;	/* x is inf or NaN */
	    w = __ieee754_logf(fabsf(x))+ln2;
	} else {
	    float xa = fabsf(x);
	    if (ix>0x40000000) {	/* 2**14 > |x| > 2.0 */
		w = __ieee754_logf(2.0f*xa+one/(__ieee754_sqrtf(xa*xa+one)+xa));
	    } else {		/* 2.0 > |x| > 2**-14 */
		float t = xa*xa;
		w =__log1pf(xa+t/(one+__ieee754_sqrtf(one+t)));
	    }
	}
	return __copysignf(w, x);
}
Example #4
0
double
__ieee754_atanh (double x)
{
  double xa = fabs (x);
  double t;
  if (isless (xa, 0.5))
    {
      if (__glibc_unlikely (xa < 0x1.0p-28))
	{
	  math_force_eval (huge + x);
	  math_check_force_underflow (x);
	  return x;
	}

      t = xa + xa;
      t = 0.5 * __log1p (t + t * xa / (1.0 - xa));
    }
  else if (__glibc_likely (isless (xa, 1.0)))
    t = 0.5 * __log1p ((xa + xa) / (1.0 - xa));
  else
    {
      if (isgreater (xa, 1.0))
	return (x - x) / (x - x);

      return x / 0.0;
    }

  return __copysign (t, x);
}
Example #5
0
long double __asinhl(long double x)
{
	long double t,w;
	int64_t hx,ix;
	double xhi;

	xhi = ldbl_high (x);
	EXTRACT_WORDS64 (hx, xhi);
	ix = hx&0x7fffffffffffffffLL;
	if(ix>=0x7ff0000000000000LL) return x+x;	/* x is inf or NaN */
	if(ix< 0x3c70000000000000LL) {	/* |x|<2**-56 */
	    math_check_force_underflow (x);
	    if(huge+x>one) return x;	/* return x inexact except 0 */
	}
	if(ix>0x4370000000000000LL) {	/* |x| > 2**56 */
	    w = __ieee754_logl(fabsl(x))+ln2;
	} else if (ix>0x4000000000000000LL) {	/* 2**56 >= |x| > 2.0 */
	    t = fabs(x);
	    w = __ieee754_logl(2.0*t+one/(sqrtl(x*x+one)+t));
	} else {		/* 2.0 >= |x| >= 2**-56 */
	    t = x*x;
	    w =__log1pl(fabsl(x)+t/(one+sqrtl(one+t)));
	}
	if(hx>0) return w; else return -w;
}
Example #6
0
__float128
sinhq (__float128 x)
{
  __float128 t, w, h;
  uint32_t jx, ix;
  ieee854_float128 u;

  /* Words of |x|. */
  u.value = x;
  jx = u.words32.w0;
  ix = jx & 0x7fffffff;

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

  h = 0.5Q;
  if (jx & 0x80000000)
    h = -h;

  /* Absolute value of x.  */
  u.words32.w0 = ix;

  /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */
  if (ix <= 0x40044000)
    {
      if (ix < 0x3fc60000) /* |x| < 2^-57 */
	{
	  math_check_force_underflow (x);
	  if (shuge + x > one)
	    return x;		/* sinh(tiny) = tiny with inexact */
	}
      t = expm1q (u.value);
      if (ix < 0x3fff0000)
	return h * (2.0Q * t - t * t / (t + one));
      return h * (t + t / (t + one));
    }

  /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */
  if (ix <= 0x400c62e3) /* 11356.375 */
    return h * expq (u.value);

  /* |x| in [log(maxdouble), overflowthreshold]
     Overflow threshold is log(2 * maxdouble).  */
  if (u.value <= ovf_thresh)
    {
      w = expq (0.5Q * u.value);
      t = h * w;
      return t * w;
    }

  /* |x| > overflowthreshold, sinhq(x) overflow */
  return x * shuge;
}
Example #7
0
_Float128
__tanhl (_Float128 x)
{
  _Float128 t, z;
  uint32_t jx, ix;
  ieee854_long_double_shape_type u;

  /* Words of |x|. */
  u.value = x;
  jx = u.parts32.w0;
  ix = jx & 0x7fffffff;
  /* x is INF or NaN */
  if (ix >= 0x7fff0000)
    {
      /* for NaN it's not important which branch: tanhl(NaN) = NaN */
      if (jx & 0x80000000)
	return one / x - one;	/* tanhl(-inf)= -1; */
      else
	return one / x + one;	/* tanhl(+inf)=+1 */
    }

  /* |x| < 40 */
  if (ix < 0x40044000)
    {
      if (u.value == 0)
	return x;		/* x == +- 0 */
      if (ix < 0x3fc60000)	/* |x| < 2^-57 */
	{
	  math_check_force_underflow (x);
	  return x * (one + tiny); /* tanh(small) = small */
	}
      u.parts32.w0 = ix;	/* Absolute value of x.  */
      if (ix >= 0x3fff0000)
	{			/* |x| >= 1  */
	  t = __expm1l (two * u.value);
	  z = one - two / (t + two);
	}
      else
	{
	  t = __expm1l (-two * u.value);
	  z = -t / (t + two);
	}
      /* |x| > 40, return +-1 */
    }
  else
    {
      z = one - tiny;		/* raised inexact flag */
    }
  return (jx & 0x80000000) ? -z : z;
}
Example #8
0
float __atanf(float x)
{
	float w,s1,s2,z;
	int32_t ix,hx,id;

	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix>=0x4c000000) {	/* if |x| >= 2^25 */
	    if(ix>0x7f800000)
		return x+x;		/* NaN */
	    if(hx>0) return  atanhi[3]+atanlo[3];
	    else     return -atanhi[3]-atanlo[3];
	} if (ix < 0x3ee00000) {	/* |x| < 0.4375 */
	    if (ix < 0x31000000) {	/* |x| < 2^-29 */
		math_check_force_underflow (x);
		if(huge+x>one) return x;	/* raise inexact */
	    }
	    id = -1;
	} else {
	x = fabsf(x);
	if (ix < 0x3f980000) {		/* |x| < 1.1875 */
	    if (ix < 0x3f300000) {	/* 7/16 <=|x|<11/16 */
		id = 0; x = ((float)2.0*x-one)/((float)2.0+x);
	    } else {			/* 11/16<=|x|< 19/16 */
		id = 1; x  = (x-one)/(x+one);
	    }
	} else {
	    if (ix < 0x401c0000) {	/* |x| < 2.4375 */
		id = 2; x  = (x-(float)1.5)/(one+(float)1.5*x);
	    } else {			/* 2.4375 <= |x| < 2^66 */
		id = 3; x  = -(float)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);
	else {
	    z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
	    return (hx<0)? -z:z;
	}
}
Example #9
0
long double
__kernel_sinl(long double x, long double y, int iy)
{
  long double absx, h, l, z, sin_l, cos_l_m1;
  int index;

  absx = fabsl (x);
  if (absx < 0.1484375L)
    {
      /* Argument is small enough to approximate it by a Chebyshev
	 polynomial of degree 17.  */
      if (absx < 0x1p-33L)
	{
	  math_check_force_underflow (x);
	  if (!((int)x)) return x;	/* generate inexact */
	}
      z = x * x;
      return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+
		       z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8)))))))));
    }
  else
    {
      /* So that we don't have to use too large polynomial,  we find
	 l and h such that x = l + h,  where fabsl(l) <= 1.0/256 with 83
	 possible values for h.  We look up cosl(h) and sinl(h) in
	 pre-computed tables,  compute cosl(l) and sinl(l) using a
	 Chebyshev polynomial of degree 10(11) and compute
	 sinl(h+l) = sinl(h)cosl(l) + cosl(h)sinl(l).  */
      index = (int) (128 * (absx - (0.1484375L - 1.0L / 256.0L)));
      h = 0.1484375L + index / 128.0;
      index *= 4;
      if (iy)
	l = (x < 0 ? -y : y) - (h - absx);
      else
	l = absx - h;
      z = l * l;
      sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5)))));
      cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5))));
      z = __sincosl_table [index + SINCOSL_SIN_HI]
	  + (__sincosl_table [index + SINCOSL_SIN_LO]
	     + (__sincosl_table [index + SINCOSL_SIN_HI] * cos_l_m1)
	     + (__sincosl_table [index + SINCOSL_COS_HI] * sin_l));
      return (x < 0) ? -z : z;
    }
}
Example #10
0
float __kernel_sinf(float x, float y, int iy)
{
	float z,r,v;
	int32_t ix;
	GET_FLOAT_WORD(ix,x);
	ix &= 0x7fffffff;			/* high word of x */
	if(ix<0x32000000)			/* |x| < 2**-27 */
	  {
	    math_check_force_underflow (x);
	    if ((int) x == 0)
	      return x;		/* generate inexact */
	  }
	z	=  x*x;
	v	=  z*x;
	r	=  S2+z*(S3+z*(S4+z*(S5+z*S6)));
	if(iy==0) return x+v*(S1+z*r);
	else      return x-((z*(half*y-v*r)-y)-v*S1);
}
Example #11
0
long double
__ieee754_sinhl(long double x)
{
	long double t,w,h;
	int64_t ix,jx;
	double xhi;

    /* High word of |x|. */
	xhi = ldbl_high (x);
	EXTRACT_WORDS64 (jx, xhi);
	ix = jx&0x7fffffffffffffffLL;

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

	h = 0.5;
	if (jx<0) h = -h;
    /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */
	if (ix < 0x4044000000000000LL) {	/* |x|<40 */
	    if (ix<0x3c90000000000000LL) {	/* |x|<2**-54 */
		math_check_force_underflow (x);
		if(shuge+x>one) return x;/* sinhl(tiny) = tiny with inexact */
	    }
	    t = __expm1l(fabsl(x));
	    if(ix<0x3ff0000000000000LL) return h*(2.0*t-t*t/(t+one));
	    w = t/(t+one);
	    return h*(t+w);
	}

    /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */
	if (ix < 0x40862e42fefa39efLL)  return h*__ieee754_expl(fabsl(x));

    /* |x| in [log(maxdouble), overflowthresold] */
	if (ix <= 0x408633ce8fb9f87eLL) {
	    w = __ieee754_expl(0.5*fabsl(x));
	    t = h*w;
	    return t*w;
	}

    /* |x| > overflowthresold, sinh(x) overflow */
	return x*shuge;
}
Example #12
0
long double
__ieee754_sinhl(long double x)
{
	long double t,w,h;
	uint32_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 */
		math_check_force_underflow (x);
		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;
}
Example #13
0
long double __tanhl(long double x)
{
	long double t,z;
	int64_t jx,ix;
	double xhi;

    /* High word of |x|. */
	xhi = ldbl_high (x);
	EXTRACT_WORDS64 (jx, xhi);
	ix = jx&0x7fffffffffffffffLL;

    /* x is INF or NaN */
	if(ix>=0x7ff0000000000000LL) {
	    if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
	    else       return one/x-one;    /* tanh(NaN) = NaN */
	}

    /* |x| < 40 */
	if (ix < 0x4044000000000000LL) {		/* |x|<40 */
	    if (ix == 0)
		return x;		/* x == +-0 */
	    if (ix<0x3c60000000000000LL) 	/* |x|<2**-57 */
	      {
		math_check_force_underflow (x);
		return x;		/* tanh(small) = small */
	      }
	    if (ix>=0x3ff0000000000000LL) {	/* |x|>=1  */
		t = __expm1l(two*fabsl(x));
		z = one - two/(t+two);
	    } else {
	        t = __expm1l(-two*fabsl(x));
	        z= -t/(t+two);
	    }
    /* |x| > 40, return +-1 */
	} else {
	    z = one - tiny;		/* raised inexact flag */
	}
	return (jx>=0)? z: -z;
}
Example #14
0
float
__ieee754_sinhf(float x)
{
	float t,w,h;
	int32_t ix,jx;

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

    /* x is INF or NaN */
	if(__builtin_expect(ix>=0x7f800000, 0)) 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 < 0x41b00000) {		/* |x|<22 */
	    if (__builtin_expect(ix<0x31800000, 0)) {	/* |x|<2**-28 */
		math_check_force_underflow (x);
		if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
	    }
	    t = __expm1f(fabsf(x));
	    if(ix<0x3f800000) return h*((float)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 < 0x42b17180)  return h*__ieee754_expf(fabsf(x));

    /* |x| in [log(maxdouble), overflowthresold] */
	if (ix<=0x42b2d4fc) {
	    w = __ieee754_expf((float)0.5*fabsf(x));
	    t = h*w;
	    return t*w;
	}

    /* |x| > overflowthresold, sinh(x) overflow */
	return math_narrow_eval (x*shuge);
}
Example #15
0
float __tanhf(float x)
{
	float t,z;
	int32_t jx,ix;

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

    /* x is INF or NaN */
	if(ix>=0x7f800000) {
	    if (jx>=0) return one/x+one;    /* tanh(+-inf)=+-1 */
	    else       return one/x-one;    /* tanh(NaN) = NaN */
	}

    /* |x| < 22 */
	if (ix < 0x41b00000) {		/* |x|<22 */
	    if (ix == 0)
		return x;		/* x == +-0 */
	    if (ix<0x24000000) 		/* |x|<2**-55 */
	      {
		math_check_force_underflow (x);
		return x*(one+x);    	/* tanh(small) = small */
	      }
	    if (ix>=0x3f800000) {	/* |x|>=1  */
		t = __expm1f(two*fabsf(x));
		z = one - two/(t+two);
	    } else {
	        t = __expm1f(-two*fabsf(x));
	        z= -t/(t+two);
	    }
    /* |x| > 22, return +-1 */
	} else {
	    z = one - tiny;		/* raised inexact flag */
	}
	return (jx>=0)? z: -z;
}
Example #16
0
long double
__expm1l (long double x)
{
  long double px, qx, xx;
  int32_t ix, sign;
  ieee854_long_double_shape_type u;
  int k;

  /* Detect infinity and NaN.  */
  u.value = x;
  ix = u.parts32.w0;
  sign = ix & 0x80000000;
  ix &= 0x7fffffff;
  if (!sign && ix >= 0x40060000)
    {
      /* If num is positive and exp >= 6 use plain exp.  */
      return __expl (x);
    }
  if (ix >= 0x7fff0000)
    {
      /* Infinity (which must be negative infinity). */
      if (((ix & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
	return -1.0L;
      /* NaN. No invalid exception. */
      return x;
    }

  /* expm1(+- 0) = +- 0.  */
  if ((ix == 0) && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0)
    return x;

  /* Minimum value.  */
  if (x < minarg)
    return (4.0/big - 1.0L);

  /* Avoid internal underflow when result does not underflow, while
     ensuring underflow (without returning a zero of the wrong sign)
     when the result does underflow.  */
  if (fabsl (x) < 0x1p-113L)
    {
      math_check_force_underflow (x);
      return x;
    }

  /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */
  xx = C1 + C2;			/* ln 2. */
  px = __floorl (0.5 + x / xx);
  k = px;
  /* remainder times ln 2 */
  x -= px * C1;
  x -= px * C2;

  /* Approximate exp(remainder ln 2).  */
  px = (((((((P7 * x
	      + P6) * x
	     + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x;

  qx = (((((((x
	      + Q7) * x
	     + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0;

  xx = x * x;
  qx = x + (0.5 * xx + xx * px / qx);

  /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2).

  We have qx = exp(remainder ln 2) - 1, so
  exp(x) - 1 = 2^k (qx + 1) - 1
             = 2^k qx + 2^k - 1.  */

  px = __ldexpl (1.0L, k);
  x = px * qx + (px - 1.0);
  return x;
}
Example #17
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);
}
Example #18
0
long double
__atanl (long double x)
{
  int32_t k, sign, lx;
  long double t, u, p, q;
  double xhi;

  xhi = ldbl_high (x);
  EXTRACT_WORDS (k, lx, xhi);
  sign = k & 0x80000000;

  /* Check for IEEE special cases.  */
  k &= 0x7fffffff;
  if (k >= 0x7ff00000)
    {
      /* NaN. */
      if (((k - 0x7ff00000) | lx) != 0)
	return (x + x);

      /* Infinity. */
      if (sign)
	return -atantbl[83];
      else
	return atantbl[83];
    }

  if (k <= 0x3c800000) /* |x| <= 2**-55.  */
    {
      math_check_force_underflow (x);
      /* Raise inexact.  */
      if (1e300L + x > 0.0)
	return x;
    }

  if (k >= 0x46c00000) /* |x| >= 2**109.  */
    {
      /* Saturate result to {-,+}pi/2.  */
      if (sign)
	return -atantbl[83];
      else
	return atantbl[83];
    }

  if (sign)
      x = -x;

  if (k >= 0x40248000) /* 10.25 */
    {
      k = 83;
      t = -1.0/x;
    }
  else
    {
      /* Index of nearest table element.
	 Roundoff to integer is asymmetrical to avoid cancellation when t < 0
         (cf. fdlibm). */
      k = 8.0 * x + 0.25;
      u = 0.125 * k;
      /* Small arctan argument.  */
      t = (x - u) / (1.0 + x * u);
    }

  /* Arctan of small argument t.  */
  u = t * t;
  p =     ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0;
  q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0;
  u = t * u * p / q  +  t;

  /* arctan x = arctan u  +  arctan t */
  u = atantbl[k] + u;
  if (sign)
    return (-u);
  else
    return u;
}
Example #19
0
double
SECTION
__sin (double x)
{
  double xx, res, t, cor, y, s, c, sn, ssn, cs, ccs, xn, a, da, db, eps, xn1,
    xn2;
  mynumber u, v;
  int4 k, m, n;
  double retval = 0;

  SET_RESTORE_ROUND_53BIT (FE_TONEAREST);

  u.x = x;
  m = u.i[HIGH_HALF];
  k = 0x7fffffff & m;		/* no sign           */
  if (k < 0x3e500000)		/* if x->0 =>sin(x)=x */
    {
      math_check_force_underflow (x);
      retval = x;
    }
 /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/
  else if (k < 0x3fd00000)
    {
      xx = x * x;
      /* Taylor series.  */
      t = POLYNOMIAL (xx) * (xx * x);
      res = x + t;
      cor = (x - res) + t;
      retval = (res == res + 1.07 * cor) ? res : slow (x);
    }				/*  else  if (k < 0x3fd00000)    */
/*---------------------------- 0.25<|x|< 0.855469---------------------- */
  else if (k < 0x3feb6000)
    {
      u.x = (m > 0) ? big + x : big - x;
      y = (m > 0) ? x - (u.x - big) : x + (u.x - big);
      xx = y * y;
      s = y + y * xx * (sn3 + xx * sn5);
      c = xx * (cs2 + xx * (cs4 + xx * cs6));
      SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs);
      if (m <= 0)
        {
          sn = -sn;
	  ssn = -ssn;
	}
      cor = (ssn + s * ccs - sn * c) + cs * s;
      res = sn + cor;
      cor = (sn - res) + cor;
      retval = (res == res + 1.096 * cor) ? res : slow1 (x);
    }				/*   else  if (k < 0x3feb6000)    */

/*----------------------- 0.855469  <|x|<2.426265  ----------------------*/
  else if (k < 0x400368fd)
    {

      y = (m > 0) ? hp0 - x : hp0 + x;
      if (y >= 0)
	{
	  u.x = big + y;
	  y = (y - (u.x - big)) + hp1;
	}
      else
	{
	  u.x = big - y;
	  y = (-hp1) - (y + (u.x - big));
	}
      res = do_cos (u, y, &cor);
      retval = (res == res + 1.020 * cor) ? ((m > 0) ? res : -res) : slow2 (x);
    }				/*   else  if (k < 0x400368fd)    */

/*-------------------------- 2.426265<|x|< 105414350 ----------------------*/
  else if (k < 0x419921FB)
    {
      t = (x * hpinv + toint);
      xn = t - toint;
      v.x = t;
      y = (x - xn * mp1) - xn * mp2;
      n = v.i[LOW_HALF] & 3;
      da = xn * mp3;
      a = y - da;
      da = (y - a) - da;
      eps = fabs (x) * 1.2e-30;

      switch (n)
	{			/* quarter of unit circle */
	case 0:
	case 2:
	  xx = a * a;
	  if (n)
	    {
	      a = -a;
	      da = -da;
	    }
	  if (xx < 0.01588)
	    {
	      /* Taylor series.  */
	      res = TAYLOR_SIN (xx, a, da, cor);
	      cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
	      retval = (res == res + cor) ? res : sloww (a, da, x);
	    }
	  else
	    {
	      if (a > 0)
		m = 1;
	      else
		{
		  m = 0;
		  a = -a;
		  da = -da;
		}
	      u.x = big + a;
	      y = a - (u.x - big);
	      res = do_sin (u, y, da, &cor);
	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
	      retval = ((res == res + cor) ? ((m) ? res : -res)
			: sloww1 (a, da, x, m));
	    }
	  break;

	case 1:
	case 3:
	  if (a < 0)
	    {
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big) + da;
	  res = do_cos (u, y, &cor);
	  cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
	  retval = ((res == res + cor) ? ((n & 2) ? -res : res)
		    : sloww2 (a, da, x, n));
	  break;
	}
    }				/*   else  if (k <  0x419921FB )    */

/*---------------------105414350 <|x|< 281474976710656 --------------------*/
  else if (k < 0x42F00000)
    {
      t = (x * hpinv + toint);
      xn = t - toint;
      v.x = t;
      xn1 = (xn + 8.0e22) - 8.0e22;
      xn2 = xn - xn1;
      y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2);
      n = v.i[LOW_HALF] & 3;
      da = xn1 * pp3;
      t = y - da;
      da = (y - t) - da;
      da = (da - xn2 * pp3) - xn * pp4;
      a = t + da;
      da = (t - a) + da;
      eps = 1.0e-24;

      switch (n)
	{
	case 0:
	case 2:
	  xx = a * a;
	  if (n)
	    {
	      a = -a;
	      da = -da;
	    }
	  if (xx < 0.01588)
	    {
	      /* Taylor series.  */
	      res = TAYLOR_SIN (xx, a, da, cor);
	      cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps;
	      retval = (res == res + cor) ? res : bsloww (a, da, x, n);
	    }
	  else
	    {
	      double t;
	      if (a > 0)
		{
		  m = 1;
		  t = a;
		  db = da;
		}
	      else
		{
		  m = 0;
		  t = -a;
		  db = -da;
		}
	      u.x = big + t;
	      y = t - (u.x - big);
	      res = do_sin (u, y, db, &cor);
	      cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps;
	      retval = ((res == res + cor) ? ((m) ? res : -res)
			: bsloww1 (a, da, x, n));
	    }
	  break;

	case 1:
	case 3:
	  if (a < 0)
	    {
	      a = -a;
	      da = -da;
	    }
	  u.x = big + a;
	  y = a - (u.x - big) + da;
	  res = do_cos (u, y, &cor);
	  cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps;
	  retval = ((res == res + cor) ? ((n & 2) ? -res : res)
		    : bsloww2 (a, da, x, n));
	  break;
	}
    }				/*   else  if (k <  0x42F00000 )   */

/* -----------------281474976710656 <|x| <2^1024----------------------------*/
  else if (k < 0x7ff00000)
    retval = reduce_and_compute (x, 0);

/*--------------------- |x| > 2^1024 ----------------------------------*/
  else
    {
      if (k == 0x7ff00000 && u.i[LOW_HALF] == 0)
	__set_errno (EDOM);
      retval = x / x;
    }

  return retval;
}
Example #20
0
_Float128
__atanl (_Float128 x)
{
  int k, sign;
  _Float128 t, u, p, q;
  ieee854_long_double_shape_type s;

  s.value = x;
  k = s.parts32.w0;
  if (k & 0x80000000)
    sign = 1;
  else
    sign = 0;

  /* Check for IEEE special cases.  */
  k &= 0x7fffffff;
  if (k >= 0x7fff0000)
    {
      /* NaN. */
      if ((k & 0xffff) | s.parts32.w1 | s.parts32.w2 | s.parts32.w3)
	return (x + x);

      /* Infinity. */
      if (sign)
	return -atantbl[83];
      else
	return atantbl[83];
    }

  if (k <= 0x3fc50000) /* |x| < 2**-58 */
    {
      math_check_force_underflow (x);
      /* Raise inexact. */
      if (huge + x > 0.0)
	return x;
    }

  if (k >= 0x40720000) /* |x| > 2**115 */
    {
      /* Saturate result to {-,+}pi/2 */
      if (sign)
	return -atantbl[83];
      else
	return atantbl[83];
    }

  if (sign)
      x = -x;

  if (k >= 0x40024800) /* 10.25 */
    {
      k = 83;
      t = -1.0/x;
    }
  else
    {
      /* Index of nearest table element.
	 Roundoff to integer is asymmetrical to avoid cancellation when t < 0
         (cf. fdlibm). */
      k = 8.0 * x + 0.25;
      u = L(0.125) * k;
      /* Small arctan argument.  */
      t = (x - u) / (1.0 + x * u);
    }

  /* Arctan of small argument t.  */
  u = t * t;
  p =     ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0;
  q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0;
  u = t * u * p / q  +  t;

  /* arctan x = arctan u  +  arctan t */
  u = atantbl[k] + u;
  if (sign)
    return (-u);
  else
    return u;
}
Example #21
0
CFLOAT
M_DECL_FUNC (__csqrt) (CFLOAT x)
{
  CFLOAT res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__glibc_unlikely (rcls <= FP_INFINITE || icls <= FP_INFINITE))
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = M_HUGE_VAL;
	  __imag__ res = __imag__ x;
	}
      else if (rcls == FP_INFINITE)
	{
	  if (__real__ x < 0)
	    {
	      __real__ res = icls == FP_NAN ? M_NAN : 0;
	      __imag__ res = M_COPYSIGN (M_HUGE_VAL, __imag__ x);
	    }
	  else
	    {
	      __real__ res = __real__ x;
	      __imag__ res = (icls == FP_NAN
			      ? M_NAN : M_COPYSIGN (0, __imag__ x));
	    }
	}
      else
	{
	  __real__ res = M_NAN;
	  __imag__ res = M_NAN;
	}
    }
  else
    {
      if (__glibc_unlikely (icls == FP_ZERO))
	{
	  if (__real__ x < 0)
	    {
	      __real__ res = 0;
	      __imag__ res = M_COPYSIGN (M_SQRT (-__real__ x), __imag__ x);
	    }
	  else
	    {
	      __real__ res = M_FABS (M_SQRT (__real__ x));
	      __imag__ res = M_COPYSIGN (0, __imag__ x);
	    }
	}
      else if (__glibc_unlikely (rcls == FP_ZERO))
	{
	  FLOAT r;
	  if (M_FABS (__imag__ x) >= 2 * M_MIN)
	    r = M_SQRT (M_LIT (0.5) * M_FABS (__imag__ x));
	  else
	    r = M_LIT (0.5) * M_SQRT (2 * M_FABS (__imag__ x));

	  __real__ res = r;
	  __imag__ res = M_COPYSIGN (r, __imag__ x);
	}
      else
	{
	  FLOAT d, r, s;
	  int scale = 0;

	  if (M_FABS (__real__ x) > M_MAX / 4)
	    {
	      scale = 1;
	      __real__ x = M_SCALBN (__real__ x, -2 * scale);
	      __imag__ x = M_SCALBN (__imag__ x, -2 * scale);
	    }
	  else if (M_FABS (__imag__ x) > M_MAX / 4)
	    {
	      scale = 1;
	      if (M_FABS (__real__ x) >= 4 * M_MIN)
		__real__ x = M_SCALBN (__real__ x, -2 * scale);
	      else
		__real__ x = 0;
	      __imag__ x = M_SCALBN (__imag__ x, -2 * scale);
	    }
	  else if (M_FABS (__real__ x) < 2 * M_MIN
		   && M_FABS (__imag__ x) < 2 * M_MIN)
	    {
	      scale = -((M_MANT_DIG + 1) / 2);
	      __real__ x = M_SCALBN (__real__ x, -2 * scale);
	      __imag__ x = M_SCALBN (__imag__ x, -2 * scale);
	    }

	  d = M_HYPOT (__real__ x, __imag__ x);
	  /* Use the identity   2  Re res  Im res = Im x
	     to avoid cancellation error in  d +/- Re x.  */
	  if (__real__ x > 0)
	    {
	      r = M_SQRT (M_LIT (0.5) * (d + __real__ x));
	      if (scale == 1 && M_FABS (__imag__ x) < 1)
		{
		  /* Avoid possible intermediate underflow.  */
		  s = __imag__ x / r;
		  r = M_SCALBN (r, scale);
		  scale = 0;
		}
	      else
		s = M_LIT (0.5) * (__imag__ x / r);
	    }
	  else
	    {
	      s = M_SQRT (M_LIT (0.5) * (d - __real__ x));
	      if (scale == 1 && M_FABS (__imag__ x) < 1)
		{
		  /* Avoid possible intermediate underflow.  */
		  r = M_FABS (__imag__ x / s);
		  s = M_SCALBN (s, scale);
		  scale = 0;
		}
	      else
		r = M_FABS (M_LIT (0.5) * (__imag__ x / s));
	    }

	  if (scale)
	    {
	      r = M_SCALBN (r, scale);
	      s = M_SCALBN (s, scale);
	    }

	  math_check_force_underflow (r);
	  math_check_force_underflow (s);

	  __real__ res = r;
	  __imag__ res = M_COPYSIGN (s, __imag__ x);
	}
    }

  return res;
}
Example #22
0
long double
__kernel_tanl (long double x, long double y, int iy)
{
  long double z, r, v, w, s;
  int32_t ix, sign, hx, lx;
  double xhi;

  xhi = ldbl_high (x);
  EXTRACT_WORDS (hx, lx, xhi);
  ix = hx & 0x7fffffff;
  if (ix < 0x3c600000)		/* x < 2**-57 */
    {
      if ((int) x == 0)		/* generate inexact */
	{
	  if ((ix | lx | (iy + 1)) == 0)
	    return one / fabs (x);
	  else if (iy == 1)
	    {
	      math_check_force_underflow (x);
	      return x;
	    }
	  else
	    return -one / x;
	}
    }
  if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */
    {
      if ((hx & 0x80000000) != 0)
	{
	  x = -x;
	  y = -y;
	  sign = -1;
	}
      else
	sign = 1;
      z = pio4hi - x;
      w = pio4lo - y;
      x = z + w;
      y = 0.0;
    }
  z = x * x;
  r = T0 + z * (T1 + z * (T2 + z * (T3 + z * T4)));
  v = U0 + z * (U1 + z * (U2 + z * (U3 + z * (U4 + z))));
  r = r / v;

  s = z * x;
  r = y + z * (s * r + y);
  r += TH * s;
  w = x + r;
  if (ix >= 0x3fe59420)
    {
      v = (long double) iy;
      w = (v - 2.0 * (x - (w * w / (w + v) - r)));
      /* SIGN is set for arguments that reach this code, but not
	 otherwise, resulting in warnings that it may be used
	 uninitialized although in the cases where it is used it has
	 always been set.  */
      DIAG_PUSH_NEEDS_COMMENT;
      DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized");
      if (sign < 0)
	w = -w;
      DIAG_POP_NEEDS_COMMENT;
      return w;
    }
  if (iy == 1)
    return w;
  else
    {				/* if allow error up to 2 ulp,
				   simply return -1.0/(x+r) here */
      /*  compute -1.0/(x+r) accurately */
      long double u1, z1;

      u1 = ldbl_high (w);
      v = r - (u1 - x);		/* u1+v = r+x */
      z = -1.0 / w;
      z1 = ldbl_high (z);
      s = 1.0 + z1 * u1;
      return z1 + z * (s + z1 * v);
    }
}