Ejemplo n.º 1
0
__complex128
catanhq (__complex128 x)
{
  __complex128 res;
  int rcls = fpclassifyq (__real__ x);
  int icls = fpclassifyq (__imag__ x);

  if (rcls <= QUADFP_INFINITE || icls <= QUADFP_INFINITE)
    {
      if (icls == QUADFP_INFINITE)
	{
	  __real__ res = copysignq (0.0, __real__ x);
	  __imag__ res = copysignq (M_PI_2q, __imag__ x);
	}
      else if (rcls == QUADFP_INFINITE || rcls == QUADFP_ZERO)
	{
	  __real__ res = copysignq (0.0, __real__ x);
	  if (icls >= QUADFP_ZERO)
	    __imag__ res = copysignq (M_PI_2q, __imag__ x);
	  else
	    __imag__ res = nanq ("");
	}
      else
	{
	  __real__ res = nanq ("");
	  __imag__ res = nanq ("");
	}
    }
  else if (rcls == QUADFP_ZERO && icls == QUADFP_ZERO)
    {
      res = x;
    }
  else
    {
      __float128 i2, num, den;

      i2 = __imag__ x * __imag__ x;

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

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

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

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

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

  return res;
}
Ejemplo n.º 2
0
/* Square root algorithm from glibc.  */
__complex128
csqrtq (__complex128 z)
{
  __float128 re = REALPART(z), im = IMAGPART(z);
  __complex128 v;

  if (im == 0)
  {
    if (re < 0)
    {
      COMPLEX_ASSIGN (v, 0, copysignq (sqrtq (-re), im));
    }
    else
    {
      COMPLEX_ASSIGN (v, fabsq (sqrtq (re)), copysignq (0, im));
    }
  }
  else if (re == 0)
  {
    __float128 r = sqrtq (0.5 * fabsq (im));
    COMPLEX_ASSIGN (v, r, copysignq (r, im));
  }
  else
  {
    __float128 d = hypotq (re, im);
    __float128 r, s;

    /* Use the identity   2  Re res  Im res = Im x
	to avoid cancellation error in  d +/- Re x.  */
    if (re > 0)
      r = sqrtq (0.5 * d + 0.5 * re), s = (0.5 * im) / r;
    else
      s = sqrtq (0.5 * d - 0.5 * re), r = fabsq ((0.5 * im) / s);

    COMPLEX_ASSIGN (v, r, copysignq (s, im));
  }
  return v;
}
Ejemplo n.º 3
0
__complex128
cacoshq (__complex128 x)
{
  __complex128 res;
  int rcls = fpclassifyq (__real__ x);
  int icls = fpclassifyq (__imag__ x);

  if (rcls <= QUADFP_INFINITE || icls <= QUADFP_INFINITE)
    {
      if (icls == QUADFP_INFINITE)
	{
	  __real__ res = HUGE_VALQ;

	  if (rcls == QUADFP_NAN)
	    __imag__ res = nanq ("");
	  else
	    __imag__ res = copysignq ((rcls == QUADFP_INFINITE
				       ? (__real__ x < 0.0
					  ? M_PIq - M_PI_4q : M_PI_4q)
				       : M_PI_2q), __imag__ x);
	}
      else if (rcls == QUADFP_INFINITE)
	{
	  __real__ res = HUGE_VALQ;

	  if (icls >= QUADFP_ZERO)
	    __imag__ res = copysignq (signbitq (__real__ x) ? M_PIq : 0.0,
				      __imag__ x);
	  else
	    __imag__ res = nanq ("");
	}
      else
	{
	  __real__ res = nanq ("");
	  __imag__ res = nanq ("");
	}
    }
  else if (rcls == QUADFP_ZERO && icls == QUADFP_ZERO)
    {
      __real__ res = 0.0;
      __imag__ res = copysignq (M_PI_2q, __imag__ x);
    }
  /* The factor 16 is just a guess.  */
  else if (16.0Q * fabsq (__imag__ x) < fabsq (__real__ x))
    {
      /* Kahan's formula which avoid cancellation through subtraction in
	 some cases.  */
      res = 2.0Q * clogq (csqrtq ((x + 1.0Q) / 2.0Q)
			    + csqrtq ((x - 1.0Q) / 2.0Q));
      if (signbitq (__real__ res))
	__real__ res = 0.0Q;
    }
  else
    {
      __complex128 y;

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

      y = csqrtq (y);

      if (signbitq (x))
	y = -y;

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

      res = clogq (y);
    }

  return res;
}
Ejemplo n.º 4
0
Archivo: ctanhq.c Proyecto: 0day-ci/gcc
__complex128
ctanhq (__complex128 x)
{
  __complex128 res;

  if (__builtin_expect (!finiteq (__real__ x) || !finiteq (__imag__ x), 0))
    {
      if (__quadmath_isinf_nsq (__real__ x))
	{
	  __real__ res = copysignq (1.0Q, __real__ x);
	  __imag__ res = copysignq (0.0Q, __imag__ x);
	}
      else if (__imag__ x == 0.0Q)
	{
	  res = x;
	}
      else
	{
	  __real__ res = nanq ("");
	  __imag__ res = nanq ("");

#ifdef HAVE_FENV_H
	  if (__quadmath_isinf_nsq (__imag__ x))
	    feraiseexcept (FE_INVALID);
#endif
	}
    }
  else
    {
      __float128 sinix, cosix;
      __float128 den;
      const int t = (int) ((FLT128_MAX_EXP - 1) * M_LN2q / 2);
      int icls = fpclassifyq (__imag__ x);

      /* 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).  */

      if (__builtin_expect (icls != QUADFP_SUBNORMAL, 1))
	{
	  sincosq (__imag__ x, &sinix, &cosix);
	}
      else
	{
	  sinix = __imag__ x;
	  cosix = 1.0Q;
	}

      if (fabsq (__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).  */
	  __float128 exp_2t = expq (2 * t);

	  __real__ res = copysignq (1.0, __real__ x);
	  __imag__ res = 4 * sinix * cosix;
	  __real__ x = fabsq (__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 /= expq (2 * __real__ x);
	}
      else
	{
	  __float128 sinhrx, coshrx;
	  if (fabsq (__real__ x) > FLT128_MIN)
	    {
	      sinhrx = sinhq (__real__ x);
	      coshrx = coshq (__real__ x);
	    }
	  else
	    {
	      sinhrx = __real__ x;
	      coshrx = 1.0Q;
	    }

	  if (fabsq (sinhrx) > fabsq (cosix) * FLT128_EPSILON)
	    den = sinhrx * sinhrx + cosix * cosix;
	  else
	    den = cosix * cosix;
	  __real__ res = sinhrx * coshrx / den;
	  __imag__ res = sinix * cosix / den;
	}
    }

  return res;
}