Пример #1
0
__float128
tanhq (__float128 x)
{
  __float128 t, z;
  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)
    {
      /* 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.words32.w0 = ix;	/* Absolute value of x.  */
      if (ix >= 0x3fff0000)
	{			/* |x| >= 1  */
	  t = expm1q (two * u.value);
	  z = one - two / (t + two);
	}
      else
	{
	  t = expm1q (-two * u.value);
	  z = -t / (t + two);
	}
      /* |x| > 40, return +-1 */
    }
  else
    {
      z = one - tiny;		/* raised inexact flag */
    }
  return (jx & 0x80000000) ? -z : z;
}
Пример #2
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;
}
Пример #3
0
__float128
coshq (__float128 x)
{
  __float128 t, w;
  int32_t ex;
  ieee854_float128 u;

  u.value = x;
  ex = u.words32.w0 & 0x7fffffff;

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

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

  /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expq(|x|)) */
  if (ex < 0x3ffd62e4) /* 0.3465728759765625 */
    {
      t = expm1q (u.value);
      w = one + t;
      if (ex < 0x3fb80000) /* |x| < 2^-116 */
	return w;		/* cosh(tiny) = 1 */

      return one + (t * t) / (w + w);
    }

  /* |x| in [0.5*ln2,40], return (exp(|x|)+1/exp(|x|)/2; */
  if (ex < 0x40044000)
    {
      t = expq (u.value);
      return half * t + half / t;
    }

  /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */
  if (ex <= 0x400c62e3) /* 11356.375 */
    return half * expq (u.value);

  /* |x| in [log(maxdouble), overflowthresold] */
  if (u.value <= ovf_thresh)
    {
      w = expq (half * u.value);
      t = half * w;
      return t * w;
    }

  /* |x| > overflowthresold, cosh(x) overflow */
  return huge * huge;
}