Exemple #1
0
__complex__ long double
__catanl (__complex__ long double x)
{
  __complex__ long double res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls <= FP_INFINITE || icls <= FP_INFINITE, 0))
    {
      if (rcls == FP_INFINITE)
	{
	  __real__ res = __copysignl (M_PI_2l, __real__ x);
	  __imag__ res = __copysignl (0.0, __imag__ x);
	}
      else if (icls == FP_INFINITE)
	{
	  if (rcls >= FP_ZERO)
	    __real__ res = __copysignl (M_PI_2l, __real__ x);
	  else
	    __real__ res = __nanl ("");
	  __imag__ res = __copysignl (0.0, __imag__ x);
	}
      else if (icls == FP_ZERO || icls == FP_INFINITE)
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __copysignl (0.0, __imag__ x);
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");
	}
    }
  else if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      res = x;
    }
  else
    {
      long double r2, num, den;

      r2 = __real__ x * __real__ x;

      den = 1 - r2 - __imag__ x * __imag__ x;

      __real__ res = 0.5 * __ieee754_atan2l (2.0 * __real__ x, den);

      num = __imag__ x + 1.0;
      num = r2 + num * num;

      den = __imag__ x - 1.0;
      den = r2 + den * den;

      __imag__ res = 0.25 * __ieee754_logl (num / den);
    }

  return res;
}
Exemple #2
0
__complex__ long double
__catanhl (__complex__ long double x)
{
  __complex__ long double res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls <= FP_INFINITE || icls <= FP_INFINITE, 0))
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = __copysignl (0.0, __real__ x);
	  __imag__ res = __copysignl (M_PI_2l, __imag__ x);
	}
      else if (rcls == FP_INFINITE || rcls == FP_ZERO)
	{
	  __real__ res = __copysignl (0.0, __real__ x);
	  if (icls >= FP_ZERO)
	    __imag__ res = __copysignl (M_PI_2l, __imag__ x);
	  else
	    __imag__ res = __nanl ("");
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");
	}
    }
  else if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      res = x;
    }
  else
    {
      long double i2 = __imag__ x * __imag__ x;

      long double num = 1.0 + __real__ x;
      num = i2 + num * num;

      long double den = 1.0 - __real__ x;
      den = i2 + den * den;

      __real__ res = 0.25 * (__ieee754_logl (num) - __ieee754_logl (den));

      den = 1 - __real__ x * __real__ x - i2;

      __imag__ res = 0.5 * __ieee754_atan2l (2.0 * __imag__ x, den);
    }

  return res;
}
Exemple #3
0
__complex__ long double
__cprojl (__complex__ long double x)
{
  __complex__ long double res;

  if (isnan (__real__ x) && isnan (__imag__ x))
    return x;
  else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
    {
      __real__ res = INFINITY;
      __imag__ res = __copysignl (0.0, __imag__ x);
    }
  else
    {
      long double den = (__real__ x * __real__ x + __imag__ x * __imag__ x
			 + 1.0);

      __real__ res = (2.0 * __real__ x) / den;
      __imag__ res = (2.0 * __imag__ x) / den;
      /* __gcc_qmul does not respect -0.0 so we need the following fixup.  */
       if (__real__ x == 0.0)
         __real__ res = __real__ x;

       if (__imag__ x == 0.0)
         __imag__ res = __imag__ x;
    }

  return res;
}
Exemple #4
0
__complex__ long double
__clogl (__complex__ long double x)
{
  __complex__ long double result;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (rcls == FP_ZERO && icls == FP_ZERO)
    {
      /* Real and imaginary part are 0.0.  */
      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
      __imag__ result = __copysignl (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsl (__real__ x);
    }
  else if (rcls != FP_NAN && icls != FP_NAN)
    {
      /* Neither real nor imaginary part is NaN.  */
      __real__ result = __ieee754_logl (__ieee754_hypotl (__real__ x,
							  __imag__ x));
      __imag__ result = __ieee754_atan2l (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanl ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALL;
      else
	__real__ result = __nanl ("");
    }

  return result;
}
Exemple #5
0
__complex__ long double
__casinhl (__complex__ long double x)
{
  __complex__ long double res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = __copysignl (HUGE_VALL, __real__ x);

	  if (rcls == FP_NAN)
	    __imag__ res = __nanl ("");
	  else
	    __imag__ res = __copysignl (rcls >= FP_ZERO ? M_PI_2l : M_PI_4l,
					__imag__ x);
	}
      else if (rcls <= FP_INFINITE)
	{
	  __real__ res = __real__ x;
	  if ((rcls == FP_INFINITE && icls >= FP_ZERO)
	      || (rcls == FP_NAN && icls == FP_ZERO))
	    __imag__ res = __copysignl (0.0, __imag__ x);
	  else
	    __imag__ res = __nanl ("");
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");
	}
    }
  else if (rcls == FP_ZERO && icls == FP_ZERO)
    {
      res = x;
    }
  else
    {
      res = __kernel_casinhl (x, 0);
    }

  return res;
}
Exemple #6
0
__complex__ long double
__ctanl (__complex__ long double x)
{
    __complex__ long double res;

    if (!isfinite (__real__ x) || !isfinite (__imag__ x))
    {
        if (__isinfl (__imag__ x))
        {
            __real__ res = __copysignl (0.0, __real__ x);
            __imag__ res = __copysignl (1.0, __imag__ x);
        }
        else if (__real__ x == 0.0)
        {
            res = x;
        }
        else
        {
            __real__ res = __nanl ("");
            __imag__ res = __nanl ("");

#ifdef FE_INVALID
            if (__isinfl (__real__ x))
                feraiseexcept (FE_INVALID);
#endif
        }
    }
    else
    {
        long double sin2rx, cos2rx;
        long double den;

        __sincosl (2.0 * __real__ x, &sin2rx, &cos2rx);

        den = cos2rx + __ieee754_coshl (2.0 * __imag__ x);

        __real__ res = sin2rx / den;
        __imag__ res = __ieee754_sinhl (2.0 * __imag__ x) / den;
    }

    return res;
}
Exemple #7
0
__complex__ long double
__clogl (__complex__ long double x)
{
  __complex__ long double result;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      /* Real and imaginary part are 0.0.  */
      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
      __imag__ result = __copysignl (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsl (__real__ x);
    }
  else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
    {
      /* Neither real nor imaginary part is NaN.  */
      long double d;
      int scale = 0;

      if (fabsl (__real__ x) > LDBL_MAX / 2.0L
	  || fabsl (__imag__ x) > LDBL_MAX / 2.0L)
	{
	  scale = -1;
	  __real__ x = __scalbnl (__real__ x, scale);
	  __imag__ x = __scalbnl (__imag__ x, scale);
	}
      else if (fabsl (__real__ x) < LDBL_MIN
	       && fabsl (__imag__ x) < LDBL_MIN)
	{
	  scale = LDBL_MANT_DIG;
	  __real__ x = __scalbnl (__real__ x, scale);
	  __imag__ x = __scalbnl (__imag__ x, scale);
	}

      d = __ieee754_hypotl (__real__ x, __imag__ x);

      __real__ result = __ieee754_logl (d) - scale * M_LN2l;
      __imag__ result = __ieee754_atan2l (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanl ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALL;
      else
	__real__ result = __nanl ("");
    }

  return result;
}
Exemple #8
0
__complex__ long double
__cprojl (__complex__ long double x)
{
  if (__isinf_nsl (__real__ x) || __isinf_nsl (__imag__ x))
    {
      __complex__ long double res;

      __real__ res = INFINITY;
      __imag__ res = __copysignl (0.0, __imag__ x);

      return res;
    }

  return x;
}
Exemple #9
0
attribute_hidden
long double _Complex
__divtc3 (long double a, long double b, long double c, long double d)
{
  long double denom, ratio, x, y;

  /* ??? We can get better behavior from logarithmic scaling instead of
     the division.  But that would mean starting to link libgcc against
     libm.  We could implement something akin to ldexp/frexp as gcc builtins
     fairly easily...  */
  if (fabsl (c) < fabsl (d))
    {
      ratio = c / d;
      denom = (c * ratio) + d;
      x = ((a * ratio) + b) / denom;
      y = ((b * ratio) - a) / denom;
    }
  else
    {
      ratio = d / c;
      denom = (d * ratio) + c;
      x = ((b * ratio) + a) / denom;
      y = (b - (a * ratio)) / denom;
    }

  /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
     are nonzero/zero, infinite/finite, and finite/infinite.  */
  if (isnan (x) && isnan (y))
    {
      if (denom == 0.0 && (!isnan (a) || !isnan (b)))
	{
	  x = __copysignl (INFINITY, c) * a;
	  y = __copysignl (INFINITY, c) * b;
	}
      else if ((__isinf_nsl (a) || __isinf_nsl (b))
	       && isfinite (c) && isfinite (d))
	{
	  a = __copysignl (__isinf_nsl (a) ? 1 : 0, a);
	  b = __copysignl (__isinf_nsl (b) ? 1 : 0, b);
	  x = INFINITY * (a * c + b * d);
	  y = INFINITY * (b * c - a * d);
	}
      else if ((__isinf_nsl (c) || __isinf_nsl (d))
	       && isfinite (a) && isfinite (b))
	{
	  c = __copysignl (__isinf_nsl (c) ? 1 : 0, c);
	  d = __copysignl (__isinf_nsl (d) ? 1 : 0, d);
	  x = 0.0 * (a * c + b * d);
	  y = 0.0 * (b * c - a * d);
	}
    }

  return x + I * y;
}
Exemple #10
0
__complex__ long double
__cprojl (__complex__ long double x)
{
  if (isnan (__real__ x) && isnan (__imag__ x))
    return x;
  else if (!isfinite (__real__ x) || !isfinite (__imag__ x))
    {
      __complex__ long double res;

      __real__ res = INFINITY;
      __imag__ res = __copysignl (0.0, __imag__ x);

      return res;
    }

  return x;
}
Exemple #11
0
__complex__ long double
__casinl (__complex__ long double x)
{
    __complex__ long double res;

    if (isnan (__real__ x) || isnan (__imag__ x))
    {
        if (__real__ x == 0.0)
        {
            res = x;
        }
        else if (__isinfl (__real__ x) || __isinfl (__imag__ x))
        {
            __real__ res = __nanl ("");
            __imag__ res = __copysignl (HUGE_VALL, __imag__ x);
        }
        else
        {
            __real__ res = __nanl ("");
            __imag__ res = __nanl ("");
        }
    }
    else
    {
        __complex__ long double y;

        __real__ y = -__imag__ x;
        __imag__ y = __real__ x;

        y = __casinhl (y);

        __real__ res = __imag__ y;
        __imag__ res = -__real__ y;
    }

    return res;
}
Exemple #12
0
long double
__ieee754_gammal_r (long double x, int *signgamp)
{
  u_int32_t es, hx, lx;
  long double ret;

  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
    {
      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 <= -1766.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);
	      math_check_force_underflow_nonneg (ret);
	    }
	}
    }
  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;
}
Exemple #13
0
__complex__ long double
__clogl (__complex__ long double x)
{
  __complex__ long double result;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__glibc_unlikely (rcls == FP_ZERO && icls == FP_ZERO))
    {
      /* Real and imaginary part are 0.0.  */
      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
      __imag__ result = __copysignl (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsl (__real__ x);
    }
  else if (__glibc_likely (rcls != FP_NAN && icls != FP_NAN))
    {
      /* Neither real nor imaginary part is NaN.  */
      long double absx = fabsl (__real__ x), absy = fabsl (__imag__ x);
      int scale = 0;

      if (absx < absy)
	{
	  long double t = absx;
	  absx = absy;
	  absy = t;
	}

      if (absx > LDBL_MAX / 2.0L)
	{
	  scale = -1;
	  absx = __scalbnl (absx, scale);
	  absy = (absy >= LDBL_MIN * 2.0L ? __scalbnl (absy, scale) : 0.0L);
	}
      else if (absx < LDBL_MIN && absy < LDBL_MIN)
	{
	  scale = LDBL_MANT_DIG;
	  absx = __scalbnl (absx, scale);
	  absy = __scalbnl (absy, scale);
	}

      if (absx == 1.0L && scale == 0)
	{
	  __real__ result = __log1pl (absy * absy) / 2.0L;
	  math_check_force_underflow_nonneg (__real__ result);
	}
      else if (absx > 1.0L && absx < 2.0L && absy < 1.0L && scale == 0)
	{
	  long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
	  if (absy >= LDBL_EPSILON)
	    d2m1 += absy * absy;
	  __real__ result = __log1pl (d2m1) / 2.0L;
	}
      else if (absx < 1.0L
	       && absx >= 0.5L
	       && absy < LDBL_EPSILON / 2.0L
	       && scale == 0)
	{
	  long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
	  __real__ result = __log1pl (d2m1) / 2.0L;
	}
      else if (absx < 1.0L
	       && absx >= 0.5L
	       && scale == 0
	       && absx * absx + absy * absy >= 0.5L)
	{
	  long double d2m1 = __x2y2m1l (absx, absy);
	  __real__ result = __log1pl (d2m1) / 2.0L;
	}
      else
	{
	  long double d = __ieee754_hypotl (absx, absy);
	  __real__ result = __ieee754_logl (d) - scale * M_LN2l;
	}

      __imag__ result = __ieee754_atan2l (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanl ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALL;
      else
	__real__ result = __nanl ("");
    }

  return result;
}
Exemple #14
0
__complex__ long double
__ctanl (__complex__ long double x)
{
  __complex__ long double res;

  if (__builtin_expect (!isfinite (__real__ x) || !isfinite (__imag__ x), 0))
    {
      if (__isinf_nsl (__imag__ x))
	{
	  __real__ res = __copysignl (0.0, __real__ x);
	  __imag__ res = __copysignl (1.0, __imag__ x);
	}
      else if (__real__ x == 0.0)
	{
	  res = x;
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");

	  if (__isinf_nsl (__real__ x))
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      long double sinrx, cosrx;
      long double den;
      const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l / 2);
      int rcls = fpclassify (__real__ x);

      /* tan(x+iy) = (sin(2x) + i*sinh(2y))/(cos(2x) + cosh(2y))
	 = (sin(x)*cos(x) + i*sinh(y)*cosh(y)/(cos(x)^2 + sinh(y)^2). */

      if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
	{
	  __sincosl (__real__ x, &sinrx, &cosrx);
	}
      else
	{
	  sinrx = __real__ x;
	  cosrx = 1.0;
	}

      if (fabsl (__imag__ x) > t)
	{
	  /* Avoid intermediate overflow when the real part of the
	     result may be subnormal.  Ignoring negligible terms, the
	     imaginary part is +/- 1, the real part is
	     sin(x)*cos(x)/sinh(y)^2 = 4*sin(x)*cos(x)/exp(2y).  */
	  long double exp_2t = __ieee754_expl (2 * t);

	  __imag__ res = __copysignl (1.0, __imag__ x);
	  __real__ res = 4 * sinrx * cosrx;
	  __imag__ x = fabsl (__imag__ x);
	  __imag__ x -= t;
	  __real__ res /= exp_2t;
	  if (__imag__ x > t)
	    {
	      /* Underflow (original imaginary part of x has absolute
		 value > 2t).  */
	      __real__ res /= exp_2t;
	    }
	  else
	    __real__ res /= __ieee754_expl (2 * __imag__ x);
	}
      else
	{
	  long double sinhix, coshix;
	  if (fabsl (__imag__ x) > LDBL_MIN)
	    {
	      sinhix = __ieee754_sinhl (__imag__ x);
	      coshix = __ieee754_coshl (__imag__ x);
	    }
	  else
	    {
	      sinhix = __imag__ x;
	      coshix = 1.0L;
	    }

	  if (fabsl (sinhix) > fabsl (cosrx) * LDBL_EPSILON)
	    den = cosrx * cosrx + sinhix * sinhix;
	  else
	    den = cosrx * cosrx;
	  __real__ res = sinrx * cosrx / den;
	  __imag__ res = sinhix * coshix / den;
	}
    }

  return res;
}
Exemple #15
0
__complex__ long double
__catanl (__complex__ long double x)
{
  __complex__ long double res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls <= FP_INFINITE || icls <= FP_INFINITE, 0))
    {
      if (rcls == FP_INFINITE)
	{
	  __real__ res = __copysignl (M_PI_2l, __real__ x);
	  __imag__ res = __copysignl (0.0, __imag__ x);
	}
      else if (icls == FP_INFINITE)
	{
	  if (rcls >= FP_ZERO)
	    __real__ res = __copysignl (M_PI_2l, __real__ x);
	  else
	    __real__ res = __nanl ("");
	  __imag__ res = __copysignl (0.0, __imag__ x);
	}
      else if (icls == FP_ZERO || icls == FP_INFINITE)
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __copysignl (0.0, __imag__ x);
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");
	}
    }
  else if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      res = x;
    }
  else
    {
      if (fabsl (__real__ x) >= 16.0L / LDBL_EPSILON
	  || fabsl (__imag__ x) >= 16.0L / LDBL_EPSILON)
	{
	  __real__ res = __copysignl (M_PI_2l, __real__ x);
	  if (fabsl (__real__ x) <= 1.0L)
	    __imag__ res = 1.0L / __imag__ x;
	  else if (fabsl (__imag__ x) <= 1.0L)
	    __imag__ res = __imag__ x / __real__ x / __real__ x;
	  else
	    {
	      long double h = __ieee754_hypotl (__real__ x / 2.0L,
						__imag__ x / 2.0L);
	      __imag__ res = __imag__ x / h / h / 4.0L;
	    }
	}
      else
	{
	  long double den, absx, absy;

	  absx = fabsl (__real__ x);
	  absy = fabsl (__imag__ x);
	  if (absx < absy)
	    {
	      long double t = absx;
	      absx = absy;
	      absy = t;
	    }

	  if (absy < LDBL_EPSILON / 2.0L)
	    den = (1.0L - absx) * (1.0L + absx);
	  else if (absx >= 1.0L)
	    den = (1.0L - absx) * (1.0L + absx) - absy * absy;
	  else if (absx >= 0.75L || absy >= 0.5L)
	    den = -__x2y2m1l (absx, absy);
	  else
	    den = (1.0L - absx) * (1.0L + absx) - absy * absy;

	  __real__ res = 0.5L * __ieee754_atan2l (2.0L * __real__ x, den);

	  if (fabsl (__imag__ x) == 1.0L
	      && fabsl (__real__ x) < LDBL_EPSILON * LDBL_EPSILON)
	    __imag__ res = (__copysignl (0.5L, __imag__ x)
			    * (M_LN2l - __ieee754_logl (fabsl (__real__ x))));
	  else
	    {
	      long double r2 = 0.0L, num, f;

	      if (fabsl (__real__ x) >= LDBL_EPSILON * LDBL_EPSILON)
		r2 = __real__ x * __real__ x;

	      num = __imag__ x + 1.0L;
	      num = r2 + num * num;

	      den = __imag__ x - 1.0L;
	      den = r2 + den * den;

	      f = num / den;
	      if (f < 0.5L)
		__imag__ res = 0.25L * __ieee754_logl (f);
	      else
		{
		  num = 4.0L * __imag__ x;
		  __imag__ res = 0.25L * __log1pl (num / den);
		}
	    }
	}

      if (fabsl (__real__ res) < LDBL_MIN)
	{
	  volatile long double force_underflow = __real__ res * __real__ res;
	  (void) force_underflow;
	}
      if (fabsl (__imag__ res) < LDBL_MIN)
	{
	  volatile long double force_underflow = __imag__ res * __imag__ res;
	  (void) force_underflow;
	}
    }

  return res;
}
Exemple #16
0
__complex__ long double
__clog10l (__complex__ long double x)
{
  __complex__ long double result;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0))
    {
      /* Real and imaginary part are 0.0.  */
      __imag__ result = signbit (__real__ x) ? M_PIl : 0.0;
      __imag__ result = __copysignl (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsl (__real__ x);
    }
  else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
    {
      /* Neither real nor imaginary part is NaN.  */
      long double absx = fabsl (__real__ x), absy = fabsl (__imag__ x);
      int scale = 0;

      if (absx < absy)
	{
	  long double t = absx;
	  absx = absy;
	  absy = t;
	}

      if (absx > LDBL_MAX / 2.0L)
	{
	  scale = -1;
	  absx = __scalbnl (absx, scale);
	  absy = (absy >= LDBL_MIN * 2.0L ? __scalbnl (absy, scale) : 0.0L);
	}
      else if (absx < LDBL_MIN && absy < LDBL_MIN)
	{
	  scale = LDBL_MANT_DIG;
	  absx = __scalbnl (absx, scale);
	  absy = __scalbnl (absy, scale);
	}

      if (absx == 1.0L && scale == 0)
	{
	  long double absy2 = absy * absy;
	  if (absy2 <= LDBL_MIN * 2.0L * M_LN10l)
	    __real__ result
	      = (absy2 / 2.0L - absy2 * absy2 / 4.0L) * M_LOG10El;
	  else
	    __real__ result = __log1pl (absy2) * (M_LOG10El / 2.0L);
	}
      else if (absx > 1.0L && absx < 2.0L && absy < 1.0L && scale == 0)
	{
	  long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
	  if (absy >= LDBL_EPSILON)
	    d2m1 += absy * absy;
	  __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
	}
      else if (absx < 1.0L
	       && absx >= 0.75L
	       && absy < LDBL_EPSILON / 2.0L
	       && scale == 0)
	{
	  long double d2m1 = (absx - 1.0L) * (absx + 1.0L);
	  __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
	}
      else if (absx < 1.0L && (absx >= 0.75L || absy >= 0.5L) && scale == 0)
	{
	  long double d2m1 = __x2y2m1l (absx, absy);
	  __real__ result = __log1pl (d2m1) * (M_LOG10El / 2.0L);
	}
      else
	{
	  long double d = __ieee754_hypotl (absx, absy);
	  __real__ result = __ieee754_log10l (d) - scale * M_LOG10_2l;
	}

      __imag__ result = M_LOG10El * __ieee754_atan2l (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanl ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALL;
      else
	__real__ result = __nanl ("");
    }

  return result;
}
Exemple #17
0
__complex__ long double
__csinl (__complex__ long double x)
{
  __complex__ long double retval;
  int negate = signbit (__real__ x);
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  __real__ x = fabsl (__real__ x);

  if (__builtin_expect (icls >= FP_ZERO, 1))
    {
      /* Imaginary part is finite.  */
      if (__builtin_expect (rcls >= FP_ZERO, 1))
	{
	  /* Real part is finite.  */
	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
	  long double sinix, cosix;

	  if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
	    {
	      __sincosl (__real__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __real__ x;
	      cosix = 1.0;
	    }

	  if (fabsl (__imag__ x) > t)
	    {
	      long double exp_t = __ieee754_expl (t);
	      long double ix = fabsl (__imag__ x);
	      if (signbit (__imag__ x))
		cosix = -cosix;
	      ix -= t;
	      sinix *= exp_t / 2.0L;
	      cosix *= exp_t / 2.0L;
	      if (ix > t)
		{
		  ix -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	      if (ix > t)
		{
		  /* Overflow (original imaginary part of x > 3t).  */
		  __real__ retval = LDBL_MAX * sinix;
		  __imag__ retval = LDBL_MAX * cosix;
		}
	      else
		{
		  long double exp_val = __ieee754_expl (ix);
		  __real__ retval = exp_val * sinix;
		  __imag__ retval = exp_val * cosix;
		}
	    }
	  else
	    {
	      __real__ retval = __ieee754_coshl (__imag__ x) * sinix;
	      __imag__ retval = __ieee754_sinhl (__imag__ x) * cosix;
	    }

	  if (negate)
	    __real__ retval = -__real__ retval;

	  if (fabsl (__real__ retval) < LDBL_MIN)
	    {
	      volatile long double force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabsl (__imag__ retval) < LDBL_MIN)
	    {
	      volatile long double force_underflow
		= __imag__ retval * __imag__ retval;
	      (void) force_underflow;
	    }
	}
      else
	{
	  if (icls == FP_ZERO)
	    {
	      /* Imaginary part is 0.0.  */
	      __real__ retval = __nanl ("");
	      __imag__ retval = __imag__ x;

	      if (rcls == FP_INFINITE)
		feraiseexcept (FE_INVALID);
	    }
	  else
	    {
	      __real__ retval = __nanl ("");
	      __imag__ retval = __nanl ("");

	      feraiseexcept (FE_INVALID);
	    }
	}
    }
  else if (icls == FP_INFINITE)
    {
      /* Imaginary part is infinite.  */
      if (rcls == FP_ZERO)
	{
	  /* Real part is 0.0.  */
	  __real__ retval = __copysignl (0.0, negate ? -1.0 : 1.0);
	  __imag__ retval = __imag__ x;
	}
      else if (rcls > FP_ZERO)
	{
	  /* Real part is finite.  */
	  long double sinix, cosix;

	  if (__builtin_expect (rcls != FP_SUBNORMAL, 1))
	    {
	      __sincosl (__real__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __real__ x;
	      cosix = 1.0;
	    }

	  __real__ retval = __copysignl (HUGE_VALL, sinix);
	  __imag__ retval = __copysignl (HUGE_VALL, cosix);

	  if (negate)
	    __real__ retval = -__real__ retval;
	  if (signbit (__imag__ x))
	    __imag__ retval = -__imag__ retval;
	}
      else
	{
	  /* The addition raises the invalid exception.  */
	  __real__ retval = __nanl ("");
	  __imag__ retval = HUGE_VALL;

	  if (rcls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      if (rcls == FP_ZERO)
	__real__ retval = __copysignl (0.0, negate ? -1.0 : 1.0);
      else
	__real__ retval = __nanl ("");
      __imag__ retval = __nanl ("");
    }

  return retval;
}
Exemple #18
0
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;
}
Exemple #19
0
__complex__ long double
__cacoshl (__complex__ long double x)
{
  __complex__ long double res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALL;

	  if (rcls == FP_NAN)
	    __imag__ res = __nanl ("");
	  else
	    __imag__ res = __copysignl ((rcls == FP_INFINITE
					 ? (__real__ x < 0.0
					    ? M_PIl - M_PI_4l : M_PI_4l)
					 : M_PI_2l), __imag__ x);
	}
      else if (rcls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALL;

	  if (icls >= FP_ZERO)
	    __imag__ res = __copysignl (signbit (__real__ x) ? M_PIl : 0.0,
					__imag__ x);
	  else
	    __imag__ res = __nanl ("");
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");
	}
    }
  else if (rcls == FP_ZERO && icls == FP_ZERO)
    {
      __real__ res = 0.0;
      __imag__ res = __copysignl (M_PI_2l, __imag__ x);
    }
  /* The factor 16 is just a guess.  */
  else if (16.0L * fabsl (__imag__ x) < fabsl (__real__ x))
    {
      /* Kahan's formula which avoid cancellation through subtraction in
	 some cases.  */
      res = 2.0L * __clogl (__csqrtl ((x + 1.0L) / 2.0L)
			    + __csqrtl ((x - 1.0L) / 2.0L));
      if (signbit (__real__ res))
	__real__ res = 0.0L;
    }
  else
    {
      __complex__ long double y;

      __real__ y = (__real__ x - __imag__ x) * (__real__ x + __imag__ x) - 1.0;
      __imag__ y = 2.0 * __real__ x * __imag__ x;

      y = __csqrtl (y);

      if (signbit (__real__ x))
	y = -y;

      __real__ y += __real__ x;
      __imag__ y += __imag__ x;

      res = __clogl (y);
    }

  return res;
}
__complex__ long double
__cacoshl (__complex__ long double x)
{
  __complex__ long double res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (rcls <= FP_INFINITE || icls <= FP_INFINITE)
    {
      if (icls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALL;

	  if (rcls == FP_NAN)
	    __imag__ res = __nanl ("");
	  else
	    __imag__ res = __copysignl ((rcls == FP_INFINITE
					 ? (__real__ x < 0.0
					    ? M_PIl - M_PI_4l : M_PI_4l)
					 : M_PI_2l), __imag__ x);
	}
      else if (rcls == FP_INFINITE)
	{
	  __real__ res = HUGE_VALL;

	  if (icls >= FP_ZERO)
	    __imag__ res = __copysignl (signbit (__real__ x) ? M_PIl : 0.0,
					__imag__ x);
	  else
	    __imag__ res = __nanl ("");
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");
	}
    }
  else if (rcls == FP_ZERO && icls == FP_ZERO)
    {
      __real__ res = 0.0;
      __imag__ res = __copysignl (M_PI_2l, __imag__ x);
    }
  else
    {
      __complex__ long double y;

      __real__ y = (__real__ x - __imag__ x) * (__real__ x + __imag__ x) - 1.0;
      __imag__ y = 2.0 * __real__ x * __imag__ x;

      y = __csqrtl (y);

      if (__real__ x < 0.0)
	y = -y;

      __real__ y += __real__ x;
      __imag__ y += __imag__ x;

      res = __clogl (y);
    }

  return res;
}
Exemple #21
0
attribute_hidden
long double _Complex
__multc3 (long double a, long double b, long double c, long double d)
{
  long double ac, bd, ad, bc, x, y;

  ac = a * c;
  bd = b * d;
  ad = a * d;
  bc = b * c;

  x = ac - bd;
  y = ad + bc;

  if (isnan (x) && isnan (y))
    {
      /* Recover infinities that computed as NaN + iNaN.  */
      bool recalc = 0;
      if (__isinf_nsl (a) || __isinf_nsl (b))
	{
	  /* z is infinite.  "Box" the infinity and change NaNs in
	     the other factor to 0.  */
	  a = __copysignl (__isinf_nsl (a) ? 1 : 0, a);
	  b = __copysignl (__isinf_nsl (b) ? 1 : 0, b);
	  if (isnan (c)) c = __copysignl (0, c);
	  if (isnan (d)) d = __copysignl (0, d);
	  recalc = 1;
	}
     if (__isinf_nsl (c) || __isinf_nsl (d))
	{
	  /* w is infinite.  "Box" the infinity and change NaNs in
	     the other factor to 0.  */
	  c = __copysignl (__isinf_nsl (c) ? 1 : 0, c);
	  d = __copysignl (__isinf_nsl (d) ? 1 : 0, d);
	  if (isnan (a)) a = __copysignl (0, a);
	  if (isnan (b)) b = __copysignl (0, b);
	  recalc = 1;
	}
     if (!recalc
	  && (__isinf_nsl (ac) || __isinf_nsl (bd)
	      || __isinf_nsl (ad) || __isinf_nsl (bc)))
	{
	  /* Recover infinities from overflow by changing NaNs to 0.  */
	  if (isnan (a)) a = __copysignl (0, a);
	  if (isnan (b)) b = __copysignl (0, b);
	  if (isnan (c)) c = __copysignl (0, c);
	  if (isnan (d)) d = __copysignl (0, d);
	  recalc = 1;
	}
      if (recalc)
	{
	  x = INFINITY * (a * c - b * d);
	  y = INFINITY * (a * d + b * c);
	}
    }

  return x + I * y;
}
Exemple #22
0
__complex__ long double
__csqrtl (__complex__ long double x)
{
    __complex__ long double res;
    int rcls = fpclassify (__real__ x);
    int icls = fpclassify (__imag__ x);

    if (__builtin_expect (rcls <= FP_INFINITE || icls <= FP_INFINITE, 0))
    {
        if (icls == FP_INFINITE)
        {
            __real__ res = HUGE_VALL;
            __imag__ res = __imag__ x;
        }
        else if (rcls == FP_INFINITE)
        {
            if (__real__ x < 0.0)
            {
                __real__ res = icls == FP_NAN ? __nanl ("") : 0;
                __imag__ res = __copysignl (HUGE_VALL, __imag__ x);
            }
            else
            {
                __real__ res = __real__ x;
                __imag__ res = (icls == FP_NAN
                                ? __nanl ("") : __copysignl (0.0, __imag__ x));
            }
        }
        else
        {
            __real__ res = __nanl ("");
            __imag__ res = __nanl ("");
        }
    }
    else
    {
        if (__builtin_expect (icls == FP_ZERO, 0))
        {
            if (__real__ x < 0.0)
            {
                __real__ res = 0.0;
                __imag__ res = __copysignl (__ieee754_sqrtl (-__real__ x),
                                            __imag__ x);
            }
            else
            {
                __real__ res = fabsl (__ieee754_sqrtl (__real__ x));
                __imag__ res = __copysignl (0.0, __imag__ x);
            }
        }
        else if (__builtin_expect (rcls == FP_ZERO, 0))
        {
            long double r = __ieee754_sqrtl (0.5 * fabsl (__imag__ x));

            __real__ res = r;
            __imag__ res = __copysignl (r, __imag__ x);
        }
        else
        {
            long double d, r, s;

            d = __ieee754_hypotl (__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 = __ieee754_sqrtl (0.5L * d + 0.5L * __real__ x);
                s = (0.5L * __imag__ x) / r;
            }
            else
            {
                s = __ieee754_sqrtl (0.5L * d - 0.5L * __real__ x);
                r = fabsl ((0.5L * __imag__ x) / s);
            }

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

    return res;
}
Exemple #23
0
__complex__ long double
__cexpl (__complex__ long double x)
{
  __complex__ long double retval;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__glibc_likely (rcls >= FP_ZERO))
    {
      /* Real part is finite.  */
      if (__glibc_likely (icls >= FP_ZERO))
	{
	  /* Imaginary part is finite.  */
	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
	  long double sinix, cosix;

	  if (__glibc_likely (icls != FP_SUBNORMAL))
	    {
	      __sincosl (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0;
	    }

	  if (__real__ x > t)
	    {
	      long double exp_t = __ieee754_expl (t);
	      __real__ x -= t;
	      sinix *= exp_t;
	      cosix *= exp_t;
	      if (__real__ x > t)
		{
		  __real__ x -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	    }
	  if (__real__ x > t)
	    {
	      /* Overflow (original real part of x > 3t).  */
	      __real__ retval = LDBL_MAX * cosix;
	      __imag__ retval = LDBL_MAX * sinix;
	    }
	  else
	    {
	      long double exp_val = __ieee754_expl (__real__ x);
	      __real__ retval = exp_val * cosix;
	      __imag__ retval = exp_val * sinix;
	    }
	  if (fabsl (__real__ retval) < LDBL_MIN)
	    {
	      volatile long double force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabsl (__imag__ retval) < LDBL_MIN)
	    {
	      volatile long double force_underflow
		= __imag__ retval * __imag__ retval;
	      (void) force_underflow;
	    }
	}
      else
	{
	  /* If the imaginary part is +-inf or NaN and the real part
	     is not +-inf the result is NaN + iNaN.  */
	  __real__ retval = __nanl ("");
	  __imag__ retval = __nanl ("");

	  feraiseexcept (FE_INVALID);
	}
    }
  else if (__glibc_likely (rcls == FP_INFINITE))
    {
      /* Real part is infinite.  */
      if (__glibc_likely (icls >= FP_ZERO))
	{
	  /* Imaginary part is finite.  */
	  long double value = signbit (__real__ x) ? 0.0 : HUGE_VALL;

	  if (icls == FP_ZERO)
	    {
	      /* Imaginary part is 0.0.  */
	      __real__ retval = value;
	      __imag__ retval = __imag__ x;
	    }
	  else
	    {
	      long double sinix, cosix;

	      if (__glibc_likely (icls != FP_SUBNORMAL))
	        {
		  __sincosl (__imag__ x, &sinix, &cosix);
	        }
	      else
		{
		  sinix = __imag__ x;
		  cosix = 1.0;
		}

	      __real__ retval = __copysignl (value, cosix);
	      __imag__ retval = __copysignl (value, sinix);
	    }
	}
      else if (signbit (__real__ x) == 0)
	{
	  __real__ retval = HUGE_VALL;
	  __imag__ retval = __nanl ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
      else
	{
	  __real__ retval = 0.0;
	  __imag__ retval = __copysignl (0.0, __imag__ x);
	}
    }
  else
    {
      /* If the real part is NaN the result is NaN + iNaN unless the
	 imaginary part is zero.  */
      __real__ retval = __nanl ("");
      if (icls == FP_ZERO)
	__imag__ retval = __imag__ x;
      else
	{
	  __imag__ retval = __nanl ("");

	  if (rcls != FP_NAN || icls != FP_NAN)
	    feraiseexcept (FE_INVALID);
	}
    }

  return retval;
}
Exemple #24
0
__complex__ long double
__kernel_casinhl (__complex__ long double x, int adj)
{
  __complex__ long double res;
  long double rx, ix;
  __complex__ long double y;

  /* Avoid cancellation by reducing to the first quadrant.  */
  rx = fabsl (__real__ x);
  ix = fabsl (__imag__ x);

  if (rx >= 1.0L / LDBL_EPSILON || ix >= 1.0L / LDBL_EPSILON)
    {
      /* For large x in the first quadrant, x + csqrt (1 + x * x)
	 is sufficiently close to 2 * x to make no significant
	 difference to the result; avoid possible overflow from
	 the squaring and addition.  */
      __real__ y = rx;
      __imag__ y = ix;

      if (adj)
	{
	  long double t = __real__ y;
	  __real__ y = __copysignl (__imag__ y, __imag__ x);
	  __imag__ y = t;
	}

      res = __clogl (y);
      __real__ res += M_LN2l;
    }
  else if (rx >= 0.5L && ix < LDBL_EPSILON / 8.0L)
    {
      long double s = __ieee754_hypotl (1.0L, rx);

      __real__ res = __ieee754_logl (rx + s);
      if (adj)
	__imag__ res = __ieee754_atan2l (s, __imag__ x);
      else
	__imag__ res = __ieee754_atan2l (ix, s);
    }
  else if (rx < LDBL_EPSILON / 8.0L && ix >= 1.5L)
    {
      long double s = __ieee754_sqrtl ((ix + 1.0L) * (ix - 1.0L));

      __real__ res = __ieee754_logl (ix + s);
      if (adj)
	__imag__ res = __ieee754_atan2l (rx, __copysignl (s, __imag__ x));
      else
	__imag__ res = __ieee754_atan2l (s, rx);
    }
  else if (ix > 1.0L && ix < 1.5L && rx < 0.5L)
    {
      if (rx < LDBL_EPSILON * LDBL_EPSILON)
	{
	  long double ix2m1 = (ix + 1.0L) * (ix - 1.0L);
	  long double s = __ieee754_sqrtl (ix2m1);

	  __real__ res = __log1pl (2.0L * (ix2m1 + ix * s)) / 2.0L;
	  if (adj)
	    __imag__ res = __ieee754_atan2l (rx, __copysignl (s, __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2l (s, rx);
	}
      else
	{
	  long double ix2m1 = (ix + 1.0L) * (ix - 1.0L);
	  long double rx2 = rx * rx;
	  long double f = rx2 * (2.0L + rx2 + 2.0L * ix * ix);
	  long double d = __ieee754_sqrtl (ix2m1 * ix2m1 + f);
	  long double dp = d + ix2m1;
	  long double dm = f / dp;
	  long double r1 = __ieee754_sqrtl ((dm + rx2) / 2.0L);
	  long double r2 = rx * ix / r1;

	  __real__ res
	    = __log1pl (rx2 + dp + 2.0L * (rx * r1 + ix * r2)) / 2.0L;
	  if (adj)
	    __imag__ res = __ieee754_atan2l (rx + r1, __copysignl (ix + r2,
								   __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2l (ix + r2, rx + r1);
	}
    }
  else if (ix == 1.0L && rx < 0.5L)
    {
      if (rx < LDBL_EPSILON / 8.0L)
	{
	  __real__ res = __log1pl (2.0L * (rx + __ieee754_sqrtl (rx))) / 2.0L;
	  if (adj)
	    __imag__ res = __ieee754_atan2l (__ieee754_sqrtl (rx),
					     __copysignl (1.0L, __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2l (1.0L, __ieee754_sqrtl (rx));
	}
      else
	{
	  long double d = rx * __ieee754_sqrtl (4.0L + rx * rx);
	  long double s1 = __ieee754_sqrtl ((d + rx * rx) / 2.0L);
	  long double s2 = __ieee754_sqrtl ((d - rx * rx) / 2.0L);

	  __real__ res = __log1pl (rx * rx + d + 2.0L * (rx * s1 + s2)) / 2.0L;
	  if (adj)
	    __imag__ res = __ieee754_atan2l (rx + s1,
					     __copysignl (1.0L + s2,
							  __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2l (1.0L + s2, rx + s1);
	}
    }
  else if (ix < 1.0L && rx < 0.5L)
    {
      if (ix >= LDBL_EPSILON)
	{
	  if (rx < LDBL_EPSILON * LDBL_EPSILON)
	    {
	      long double onemix2 = (1.0L + ix) * (1.0L - ix);
	      long double s = __ieee754_sqrtl (onemix2);

	      __real__ res = __log1pl (2.0L * rx / s) / 2.0L;
	      if (adj)
		__imag__ res = __ieee754_atan2l (s, __imag__ x);
	      else
		__imag__ res = __ieee754_atan2l (ix, s);
	    }
	  else
	    {
	      long double onemix2 = (1.0L + ix) * (1.0L - ix);
	      long double rx2 = rx * rx;
	      long double f = rx2 * (2.0L + rx2 + 2.0L * ix * ix);
	      long double d = __ieee754_sqrtl (onemix2 * onemix2 + f);
	      long double dp = d + onemix2;
	      long double dm = f / dp;
	      long double r1 = __ieee754_sqrtl ((dp + rx2) / 2.0L);
	      long double r2 = rx * ix / r1;

	      __real__ res
		= __log1pl (rx2 + dm + 2.0L * (rx * r1 + ix * r2)) / 2.0L;
	      if (adj)
		__imag__ res = __ieee754_atan2l (rx + r1,
						 __copysignl (ix + r2,
							      __imag__ x));
	      else
		__imag__ res = __ieee754_atan2l (ix + r2, rx + r1);
	    }
	}
      else
	{
	  long double s = __ieee754_hypotl (1.0L, rx);

	  __real__ res = __log1pl (2.0L * rx * (rx + s)) / 2.0L;
	  if (adj)
	    __imag__ res = __ieee754_atan2l (s, __imag__ x);
	  else
	    __imag__ res = __ieee754_atan2l (ix, s);
	}
      if (__real__ res < LDBL_MIN)
	{
	  volatile long double force_underflow = __real__ res * __real__ res;
	  (void) force_underflow;
	}
    }
  else
    {
      __real__ y = (rx - ix) * (rx + ix) + 1.0L;
      __imag__ y = 2.0L * rx * ix;

      y = __csqrtl (y);

      __real__ y += rx;
      __imag__ y += ix;

      if (adj)
	{
	  long double t = __real__ y;
	  __real__ y = __copysignl (__imag__ y, __imag__ x);
	  __imag__ y = t;
	}

      res = __clogl (y);
    }

  /* Give results the correct sign for the original argument.  */
  __real__ res = __copysignl (__real__ res, __real__ x);
  __imag__ res = __copysignl (__imag__ res, (adj ? 1.0L : __imag__ x));

  return res;
}
Exemple #25
0
__complex__ long double
__cexpl (__complex__ long double x)
{
  __complex__ long double retval;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__builtin_expect (rcls >= FP_ZERO, 1))
    {
      /* Real part is finite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
	  long double sinix, cosix;

	  __sincosl (__imag__ x, &sinix, &cosix);

	  if (__real__ x > t)
	    {
	      long double exp_t = __ieee754_expl (t);
	      __real__ x -= t;
	      sinix *= exp_t;
	      cosix *= exp_t;
	      if (__real__ x > t)
		{
		  __real__ x -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	    }
	  if (__real__ x > t)
	    {
	      /* Overflow (original real part of x > 3t).  */
	      __real__ retval = LDBL_MAX * cosix;
	      __imag__ retval = LDBL_MAX * sinix;
	    }
	  else
	    {
	      long double exp_val = __ieee754_expl (__real__ x);
	      __real__ retval = exp_val * cosix;
	      __imag__ retval = exp_val * sinix;
	    }
	}
      else
	{
	  /* If the imaginary part is +-inf or NaN and the real part
	     is not +-inf the result is NaN + iNaN.  */
	  __real__ retval = __nanl ("");
	  __imag__ retval = __nanl ("");

	  feraiseexcept (FE_INVALID);
	}
    }
  else if (__builtin_expect (rcls == FP_INFINITE, 1))
    {
      /* Real part is infinite.  */
      if (__builtin_expect (icls >= FP_ZERO, 1))
	{
	  /* Imaginary part is finite.  */
	  long double value = signbit (__real__ x) ? 0.0 : HUGE_VALL;

	  if (icls == FP_ZERO)
	    {
	      /* Imaginary part is 0.0.  */
	      __real__ retval = value;
	      __imag__ retval = __imag__ x;
	    }
	  else
	    {
	      long double sinix, cosix;

	      __sincosl (__imag__ x, &sinix, &cosix);

	      __real__ retval = __copysignl (value, cosix);
	      __imag__ retval = __copysignl (value, sinix);
	    }
	}
      else if (signbit (__real__ x) == 0)
	{
	  __real__ retval = HUGE_VALL;
	  __imag__ retval = __nanl ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
      else
	{
	  __real__ retval = 0.0;
	  __imag__ retval = __copysignl (0.0, __imag__ x);
	}
    }
  else
    {
      /* If the real part is NaN the result is NaN + iNaN.  */
      __real__ retval = __nanl ("");
      __imag__ retval = __nanl ("");

      if (rcls != FP_NAN || icls != FP_NAN)
	feraiseexcept (FE_INVALID);
    }

  return retval;
}
long double
__kernel_standard_l (long double x, long double y, int type)
{
  double dx, dy;
  struct exception exc;

  if (isfinite (x))
    {
      long double ax = fabsl (x);
      if (ax > DBL_MAX)
	dx = __copysignl (DBL_MAX, x);
      else if (ax > 0 && ax < DBL_MIN)
	dx = __copysignl (DBL_MIN, x);
      else
	dx = x;
    }
  else
    dx = x;
  if (isfinite (y))
    {
      long double ay = fabsl (y);
      if (ay > DBL_MAX)
	dy = __copysignl (DBL_MAX, y);
      else if (ay > 0 && ay < DBL_MIN)
	dy = __copysignl (DBL_MIN, y);
      else
	dy = y;
    }
  else
    dy = y;

  switch (type)
    {
    case 221:
      /* powl (x, y) overflow.  */
      exc.arg1 = dx;
      exc.arg2 = dy;
      exc.type = OVERFLOW;
      exc.name = "powl";
      if (_LIB_VERSION == _SVID_)
	{
	  exc.retval = HUGE;
	  y *= 0.5;
	  if (x < zero && __rintl (y) != y)
	    exc.retval = -HUGE;
	}
      else
	{
	  exc.retval = HUGE_VAL;
	  y *= 0.5;
	  if (x < zero && __rintl (y) != y)
	    exc.retval = -HUGE_VAL;
	}
      if (_LIB_VERSION == _POSIX_)
	__set_errno (ERANGE);
      else if (!matherr (&exc))
	__set_errno (ERANGE);
      return exc.retval;

    case 222:
      /* powl (x, y) underflow.  */
      exc.arg1 = dx;
      exc.arg2 = dy;
      exc.type = UNDERFLOW;
      exc.name = "powl";
      exc.retval = zero;
      y *= 0.5;
      if (x < zero && __rintl (y) != y)
	exc.retval = -zero;
      if (_LIB_VERSION == _POSIX_)
	__set_errno (ERANGE);
      else if (!matherr (&exc))
	__set_errno (ERANGE);
      return exc.retval;

    default:
      return __kernel_standard (dx, dy, type);
    }
}
Exemple #27
0
__complex__ long double
__ccoshl (__complex__ long double x)
{
  __complex__ long double retval;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__glibc_likely (rcls >= FP_ZERO))
    {
      /* Real part is finite.  */
      if (__glibc_likely (icls >= FP_ZERO))
	{
	  /* Imaginary part is finite.  */
	  const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l);
	  long double sinix, cosix;

	  if (__glibc_likely (fabsl (__imag__ x) > LDBL_MIN))
	    {
	      __sincosl (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0;
	    }

	  if (fabsl (__real__ x) > t)
	    {
	      long double exp_t = __ieee754_expl (t);
	      long double rx = fabsl (__real__ x);
	      if (signbit (__real__ x))
		sinix = -sinix;
	      rx -= t;
	      sinix *= exp_t / 2.0L;
	      cosix *= exp_t / 2.0L;
	      if (rx > t)
		{
		  rx -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	      if (rx > t)
		{
		  /* Overflow (original real part of x > 3t).  */
		  __real__ retval = LDBL_MAX * cosix;
		  __imag__ retval = LDBL_MAX * sinix;
		}
	      else
		{
		  long double exp_val = __ieee754_expl (rx);
		  __real__ retval = exp_val * cosix;
		  __imag__ retval = exp_val * sinix;
		}
	    }
	  else
	    {
	      __real__ retval = __ieee754_coshl (__real__ x) * cosix;
	      __imag__ retval = __ieee754_sinhl (__real__ x) * sinix;
	    }

	  math_check_force_underflow_complex (retval);
	}
      else
	{
	  __imag__ retval = __real__ x == 0.0 ? 0.0 : __nanl ("");
	  __real__ retval = __nanl ("") + __nanl ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
    }
  else if (rcls == FP_INFINITE)
    {
      /* Real part is infinite.  */
      if (__glibc_likely (icls > FP_ZERO))
	{
	  /* Imaginary part is finite.  */
	  long double sinix, cosix;

	  if (__glibc_likely (fabsl (__imag__ x) > LDBL_MIN))
	    {
	      __sincosl (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0;
	    }

	  __real__ retval = __copysignl (HUGE_VALL, cosix);
	  __imag__ retval = (__copysignl (HUGE_VALL, sinix)
			     * __copysignl (1.0, __real__ x));
	}
      else if (icls == FP_ZERO)
	{
	  /* Imaginary part is 0.0.  */
	  __real__ retval = HUGE_VALL;
	  __imag__ retval = __imag__ x * __copysignl (1.0, __real__ x);
	}
      else
	{
	  /* The addition raises the invalid exception.  */
	  __real__ retval = HUGE_VALL;
	  __imag__ retval = __nanl ("") + __nanl ("");

	  if (icls == FP_INFINITE)
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      __real__ retval = __nanl ("");
      __imag__ retval = __imag__ x == 0.0 ? __imag__ x : __nanl ("");
    }

  return retval;
}
Exemple #28
0
__complex__ long double
__ctanhl (__complex__ long double x)
{
  __complex__ long double res;

  if (!isfinite (__real__ x) || !isfinite (__imag__ x))
    {
      if (__isinfl (__real__ x))
	{
	  __real__ res = __copysignl (1.0L, __real__ x);
	  __imag__ res = __copysignl (0.0L, __imag__ x);
	}
      else if (__imag__ x == 0.0)
	{
	  res = x;
	}
      else
	{
	  __real__ res = __nanl ("");
	  __imag__ res = __nanl ("");

#ifdef FE_INVALID
	  if (__isinfl (__imag__ x))
	    feraiseexcept (FE_INVALID);
#endif
	}
    }
  else
    {
      long double sinix, cosix;
      long double den;
      const int t = (int) ((LDBL_MAX_EXP - 1) * M_LN2l / 2.0L);

      /* tanh(x+iy) = (sinh(2x) + i*sin(2y))/(cosh(2x) + cos(2y))
        = (sinh(x)*cosh(x) + i*sin(y)*cos(y))/(sinh(x)^2 + cos(y)^2).  */

      __sincosl (__imag__ x, &sinix, &cosix);

      if (fabsl (__real__ x) > t)
	{
	  /* Avoid intermediate overflow when the imaginary part of
	     the result may be subnormal.  Ignoring negligible terms,
	     the real part is +/- 1, the imaginary part is
	     sin(y)*cos(y)/sinh(x)^2 = 4*sin(y)*cos(y)/exp(2x).  */
	  long double exp_2t = __ieee754_expl (2 * t);
	  __real__ res = __copysignl (1.0L, __real__ x);
	  __imag__ res = 4 * sinix * cosix;
	  __real__ x = fabsl (__real__ x);
	  __real__ x -= t;
	  __imag__ res /= exp_2t;
	  if (__real__ x > t)
	    {
	      /* Underflow (original real part of x has absolute value
		 > 2t).  */
	      __imag__ res /= exp_2t;
	    }
	  else
	    __imag__ res /= __ieee754_expl (2.0L * __real__ x);
	}
      else
	{
	  long double sinhrx, coshrx;
	  if (fabs (__real__ x) > LDBL_MIN)
	    {
	      sinhrx = __ieee754_sinhl (__real__ x);
	      coshrx = __ieee754_coshl (__real__ x);
	    }
	  else
	    {
	      sinhrx = __real__ x;
	      coshrx = 1.0L;
	    }

	  if (fabsl (sinhrx) > fabsl (cosix) * ldbl_eps)
	    den = sinhrx * sinhrx + cosix * cosix;
	  else
	    den = cosix * cosix;
	  __real__ res = sinhrx * (coshrx / den);
	  __imag__ res = sinix * (cosix / den);
	}
      /* __gcc_qmul does not respect -0.0 so we need the following fixup.  */
      if ((__real__ res == 0.0L) && (__real__ x == 0.0L))
        __real__ res = __real__ x;

      if ((__real__ res == 0.0L) && (__imag__ x == 0.0L))
        __imag__ res = __imag__ x;
    }

  return res;
}