Exemplo n.º 1
0
long double
__ieee754_atanhl(long double x)
{
	long double t;
	u_int32_t jx, ix;
	ieee854_long_double_shape_type u;

	u.value = x;
	jx = u.parts32.w0;
	ix = jx & 0x7fffffff;
	u.parts32.w0 = ix;
	if (ix >= 0x3fff0000) /* |x| >= 1.0 or infinity or NaN */
	  {
	    if (u.value == one)
	      return x/zero;
	    else
	      return (x-x)/(x-x);
	  }
	if(ix<0x3fc60000 && (huge+x)>zero)	/* x < 2^-57 */
	  {
	    if (fabsl (x) < LDBL_MIN)
	      {
		long double force_underflow = x * x;
		math_force_eval (force_underflow);
	      }
	    return x;
	  }

	if(ix<0x3ffe0000) {		/* x < 0.5 */
	    t = u.value+u.value;
	    t = 0.5*__log1pl(t+t*u.value/(one-u.value));
	} else
	    t = 0.5*__log1pl((u.value+u.value)/(one-u.value));
	if(jx & 0x80000000) return -t; else return t;
}
Exemplo n.º 2
0
long double
__ieee754_atanhl(long double x)
{
    long double t;
    int64_t hx,ix;
    u_int64_t lx __attribute__ ((unused));
    GET_LDOUBLE_WORDS64(hx,lx,x);
    ix = hx&0x7fffffffffffffffLL;
    if (ix >= 0x3ff0000000000000LL) { /* |x|>=1 */
        if (ix > 0x3ff0000000000000LL)
            return (x-x)/(x-x);
        t = fabsl (x);
        if (t > one)
            return (x-x)/(x-x);
        if (t == one)
            return x/zero;
    }
    if(ix<0x3e20000000000000LL&&(huge+x)>zero) return x;	/* x<2**-29 */
    x = fabsl (x);
    if(ix<0x3fe0000000000000LL) {		/* x < 0.5 */
        t = x+x;
        t = 0.5*__log1pl(t+t*x/(one-x));
    } else
        t = 0.5*__log1pl((x+x)/(one-x));
    if(hx>=0) return t;
    else return -t;
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
long double
__ieee754_acoshl(long double x)
{
	long double t;
	int64_t hx;
	uint64_t lx;
	double xhi, xlo;

	ldbl_unpack (x, &xhi, &xlo);
	EXTRACT_WORDS64 (hx, xhi);
	EXTRACT_WORDS64 (lx, xlo);
	if(hx<0x3ff0000000000000LL) {		/* x < 1 */
	    return (x-x)/(x-x);
	} else if(hx >=0x41b0000000000000LL) {	/* x > 2**28 */
	    if(hx >=0x7ff0000000000000LL) {	/* x is inf of NaN */
		return x+x;
	    } else
		return __ieee754_logl(x)+ln2;	/* acosh(huge)=log(2x) */
	} else if (((hx-0x3ff0000000000000LL)|(lx&0x7fffffffffffffffLL))==0) {
	    return 0.0;			/* acosh(1) = 0 */
	} else if (hx > 0x4000000000000000LL) {	/* 2**28 > x > 2 */
	    t=x*x;
	    return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one)));
	} else {			/* 1<x<2 */
	    t = x-one;
	    return __log1pl(t+__ieee754_sqrtl(2.0*t+t*t));
	}
}
Exemplo n.º 5
0
long double
__w_log1pl (long double x)
{
  if (__glibc_unlikely (islessequal (x, -1.0L)))
    {
      if (x == -1.0L)
	__set_errno (ERANGE);
      else
	__set_errno (EDOM);
    }

  return __log1pl (x);
}
Exemplo n.º 6
0
long double __asinhl(long double x)
{
	long double t,w;
	int64_t hx,ix;
	GET_LDOUBLE_MSW64(hx,x);
	ix = hx&0x7fffffffffffffffLL;
	if(ix>=0x7ff0000000000000LL) return x+x;	/* x is inf or NaN */
	if(ix< 0x3e20000000000000LL) {	/* |x|<2**-29 */
	    if(huge+x>one) return x;	/* return x inexact except 0 */
	}
	if(ix>0x41b0000000000000LL) {	/* |x| > 2**28 */
	    w = __ieee754_logl(fabs(x))+ln2;
	} else if (ix>0x4000000000000000LL) {	/* 2**28 > |x| > 2.0 */
	    t = fabs(x);
	    w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t));
	} else {		/* 2.0 > |x| > 2**-29 */
	    t = x*x;
	    w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t)));
	}
	if(hx>0) return w; else return -w;
}
Exemplo n.º 7
0
Arquivo: e_acoshl.c Projeto: dreal/tai
long double
__ieee754_acoshl(long double x)
{
	long double t;
	u_int64_t lx;
	int64_t hx;
	GET_LDOUBLE_WORDS64(hx,lx,x);
	if(hx<0x3fff000000000000LL) {		/* x < 1 */
	    return (x-x)/(x-x);
	} else if(hx >=0x4035000000000000LL) {	/* x > 2**54 */
	    if(hx >=0x7fff000000000000LL) {	/* x is inf of NaN */
		return x+x;
	    } else
		return __ieee754_logl(x)+ln2;	/* acoshl(huge)=logl(2x) */
	} else if(((hx-0x3fff000000000000LL)|lx)==0) {
	    return 0.0L;			/* acosh(1) = 0 */
	} else if (hx > 0x4000000000000000LL) {	/* 2**28 > x > 2 */
	    t=x*x;
	    return __ieee754_logl(2.0L*x-one/(x+__ieee754_sqrtl(t-one)));
	} else {			/* 1<x<2 */
	    t = x-one;
	    return __log1pl(t+__sqrtl(2.0L*t+t*t));
	}
}
Exemplo n.º 8
0
long double
__lgamma_negl (long double x, int *signgamp)
{
  /* Determine the half-integer region X lies in, handle exact
     integers and determine the sign of the result.  */
  int i = floorl (-2 * x);
  if ((i & 1) == 0 && i == -2 * x)
    return 1.0L / 0.0L;
  long double xn = ((i & 1) == 0 ? -i / 2 : (-i - 1) / 2);
  i -= 4;
  *signgamp = ((i & 2) == 0 ? -1 : 1);

  SET_RESTORE_ROUNDL (FE_TONEAREST);

  /* Expand around the zero X0 = X0_HI + X0_LO.  */
  long double x0_hi = lgamma_zeros[i][0], x0_lo = lgamma_zeros[i][1];
  long double xdiff = x - x0_hi - x0_lo;

  /* For arguments in the range -3 to -2, use polynomial
     approximations to an adjusted version of the gamma function.  */
  if (i < 2)
    {
      int j = floorl (-8 * x) - 16;
      long double xm = (-33 - 2 * j) * 0.0625L;
      long double x_adj = x - xm;
      size_t deg = poly_deg[j];
      size_t end = poly_end[j];
      long double g = poly_coeff[end];
      for (size_t j = 1; j <= deg; j++)
	g = g * x_adj + poly_coeff[end - j];
      return __log1pl (g * xdiff / (x - xn));
    }

  /* The result we want is log (sinpi (X0) / sinpi (X))
     + log (gamma (1 - X0) / gamma (1 - X)).  */
  long double x_idiff = fabsl (xn - x), x0_idiff = fabsl (xn - x0_hi - x0_lo);
  long double log_sinpi_ratio;
  if (x0_idiff < x_idiff * 0.5L)
    /* Use log not log1p to avoid inaccuracy from log1p of arguments
       close to -1.  */
    log_sinpi_ratio = __ieee754_logl (lg_sinpi (x0_idiff)
				      / lg_sinpi (x_idiff));
  else
    {
      /* Use log1p not log to avoid inaccuracy from log of arguments
	 close to 1.  X0DIFF2 has positive sign if X0 is further from
	 XN than X is from XN, negative sign otherwise.  */
      long double x0diff2 = ((i & 1) == 0 ? xdiff : -xdiff) * 0.5L;
      long double sx0d2 = lg_sinpi (x0diff2);
      long double cx0d2 = lg_cospi (x0diff2);
      log_sinpi_ratio = __log1pl (2 * sx0d2
				  * (-sx0d2 + cx0d2 * lg_cotpi (x_idiff)));
    }

  long double log_gamma_ratio;
  long double y0 = 1 - x0_hi;
  long double y0_eps = -x0_hi + (1 - y0) - x0_lo;
  long double y = 1 - x;
  long double y_eps = -x + (1 - y);
  /* We now wish to compute LOG_GAMMA_RATIO
     = log (gamma (Y0 + Y0_EPS) / gamma (Y + Y_EPS)).  XDIFF
     accurately approximates the difference Y0 + Y0_EPS - Y -
     Y_EPS.  Use Stirling's approximation.  First, we may need to
     adjust into the range where Stirling's approximation is
     sufficiently accurate.  */
  long double log_gamma_adj = 0;
  if (i < 18)
    {
      int n_up = (19 - i) / 2;
      long double ny0, ny0_eps, ny, ny_eps;
      ny0 = y0 + n_up;
      ny0_eps = y0 - (ny0 - n_up) + y0_eps;
      y0 = ny0;
      y0_eps = ny0_eps;
      ny = y + n_up;
      ny_eps = y - (ny - n_up) + y_eps;
      y = ny;
      y_eps = ny_eps;
      long double prodm1 = __lgamma_productl (xdiff, y - n_up, y_eps, n_up);
      log_gamma_adj = -__log1pl (prodm1);
    }
  long double log_gamma_high
    = (xdiff * __log1pl ((y0 - e_hi - e_lo + y0_eps) / e_hi)
       + (y - 0.5L + y_eps) * __log1pl (xdiff / y) + log_gamma_adj);
  /* Compute the sum of (B_2k / 2k(2k-1))(Y0^-(2k-1) - Y^-(2k-1)).  */
  long double y0r = 1 / y0, yr = 1 / y;
  long double y0r2 = y0r * y0r, yr2 = yr * yr;
  long double rdiff = -xdiff / (y * y0);
  long double bterm[NCOEFF];
  long double dlast = rdiff, elast = rdiff * yr * (yr + y0r);
  bterm[0] = dlast * lgamma_coeff[0];
  for (size_t j = 1; j < NCOEFF; j++)
    {
      long double dnext = dlast * y0r2 + elast;
      long double enext = elast * yr2;
      bterm[j] = dnext * lgamma_coeff[j];
      dlast = dnext;
      elast = enext;
    }
  long double log_gamma_low = 0;
  for (size_t j = 0; j < NCOEFF; j++)
    log_gamma_low += bterm[NCOEFF - 1 - j];
  log_gamma_ratio = log_gamma_high + log_gamma_low;

  return log_sinpi_ratio + log_gamma_ratio;
}
Exemplo n.º 9
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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
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;
}