Ejemplo n.º 1
0
__complex__ float
__clog10f (__complex__ float x)
{
  __complex__ float 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_PI : 0.0;
      __imag__ result = __copysignf (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsf (__real__ x);
    }
  else if (rcls != FP_NAN && icls != FP_NAN)
    {
      /* Neither real nor imaginary part is NaN.  */
      __real__ result = __ieee754_log10f (__ieee754_hypotf (__real__ x,
							    __imag__ x));
      __imag__ result = M_LOG10E * __ieee754_atan2f (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanf ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALF;
      else
	__real__ result = __nanf ("");
    }

  return result;
}
Ejemplo n.º 2
0
float
hypotf(float x, float y)	/* wrapper hypotf */
{
#ifdef _IEEE_LIBM
    return __ieee754_hypotf(x,y);
#else
    float z;
    z = __ieee754_hypotf(x,y);
    if(_LIB_VERSION == _IEEE_) return z;
    if((!finitef(z))&&finitef(x)&&finitef(y))
        /* hypot overflow */
        return (float)__kernel_standard((double)x,(double)y,104);
    else
        return z;
#endif
}
Ejemplo n.º 3
0
float
__hypotf(float x, float y)
{
	float z = __ieee754_hypotf(x,y);
	if(__builtin_expect(!__finitef(z), 0)
	   && __finitef(x) && __finitef(y) && _LIB_VERSION != _IEEE_)
	    /* hypot overflow */
	    return __kernel_standard_f(x, y, 104);

	return z;
}
Ejemplo n.º 4
0
__complex__ float
__clog10f (__complex__ float x)
{
  __complex__ float 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_PI : 0.0;
      __imag__ result = __copysignf (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsf (__real__ x);
    }
  else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
    {
      /* Neither real nor imaginary part is NaN.  */
      float d;
      int scale = 0;

      if (fabsf (__real__ x) > FLT_MAX / 2.0f
	  || fabsf (__imag__ x) > FLT_MAX / 2.0f)
	{
	  scale = -1;
	  __real__ x = __scalbnf (__real__ x, scale);
	  __imag__ x = __scalbnf (__imag__ x, scale);
	}
      else if (fabsf (__real__ x) < FLT_MIN
	       && fabsf (__imag__ x) < FLT_MIN)
	{
	  scale = FLT_MANT_DIG;
	  __real__ x = __scalbnf (__real__ x, scale);
	  __imag__ x = __scalbnf (__imag__ x, scale);
	}

      d = __ieee754_hypotf (__real__ x, __imag__ x);

      __real__ result = __ieee754_log10f (d) - scale * M_LOG10_2f;
      __imag__ result = M_LOG10E * __ieee754_atan2f (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanf ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALF;
      else
	__real__ result = __nanf ("");
    }

  return result;
}
Ejemplo n.º 5
0
    //------------------------------------------------------------------------------
    float Cmath::hypotf( float x, float y ) // wrapper hypotf
    {
        float z;
        struct fexception exc;
        z = __ieee754_hypotf( x, y );
        if( m_fdlib_version == _IEEE_ )
        {
            return z;
        }
        if( ( !finitef( z ) ) && finitef( x ) && finitef( y ) )
        {
            // hypotf(finite,finite) overflow
            exc.type = EX_OVERFLOW;
            exc.name = "hypotf";
            exc.err = 0;
            exc.arg1 = (double)x;
            exc.arg2 = (double)y;
            if( m_fdlib_version == _SVID_ )
            {
                exc.retval = Huge();
            }
            else
            {
                exc.retval = HUGE_VAL;
            }

            if( m_fdlib_version == _POSIX_ )
            {
                errno = ERANGE;
            }
            else if( !matherr( &exc ) )
            {
                errno = ERANGE;
            }

            if( exc.err != 0 )
            {
                errno = exc.err;
            }
            return (float)exc.retval;
        }
        else
        {
            return z;
        }
    }
Ejemplo n.º 6
0
__complex__ float
__clog10f (__complex__ float x)
{
  __complex__ float 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_PI_LOG10Ef : 0.0;
      __imag__ result = __copysignf (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsf (__real__ x);
    }
  else if (__glibc_likely (rcls != FP_NAN && icls != FP_NAN))
    {
      /* Neither real nor imaginary part is NaN.  */
      float absx = fabsf (__real__ x), absy = fabsf (__imag__ x);
      int scale = 0;

      if (absx < absy)
	{
	  float t = absx;
	  absx = absy;
	  absy = t;
	}

      if (absx > FLT_MAX / 2.0f)
	{
	  scale = -1;
	  absx = __scalbnf (absx, scale);
	  absy = (absy >= FLT_MIN * 2.0f ? __scalbnf (absy, scale) : 0.0f);
	}
      else if (absx < FLT_MIN && absy < FLT_MIN)
	{
	  scale = FLT_MANT_DIG;
	  absx = __scalbnf (absx, scale);
	  absy = __scalbnf (absy, scale);
	}

      if (absx == 1.0f && scale == 0)
	{
	  float absy2 = absy * absy;
	  if (absy2 <= FLT_MIN * 2.0f * (float) M_LN10)
	    {
	      float force_underflow = absy2 * absy2;
	      __real__ result = absy2 * ((float) M_LOG10E / 2.0f);
	      math_force_eval (force_underflow);
	    }
	  else
	    __real__ result = __log1pf (absy2) * ((float) M_LOG10E / 2.0f);
	}
      else if (absx > 1.0f && absx < 2.0f && absy < 1.0f && scale == 0)
	{
	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
	  if (absy >= FLT_EPSILON)
	    d2m1 += absy * absy;
	  __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
	}
      else if (absx < 1.0f
	       && absx >= 0.75f
	       && absy < FLT_EPSILON / 2.0f
	       && scale == 0)
	{
	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
	  __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
	}
      else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
	{
	  float d2m1 = __x2y2m1f (absx, absy);
	  __real__ result = __log1pf (d2m1) * ((float) M_LOG10E / 2.0f);
	}
      else
	{
	  float d = __ieee754_hypotf (absx, absy);
	  __real__ result = __ieee754_log10f (d) - scale * M_LOG10_2f;
	}

      __imag__ result = M_LOG10E * __ieee754_atan2f (__imag__ x, __real__ x);
    }
  else
    {
      __imag__ result = __nanf ("");
      if (rcls == FP_INFINITE || icls == FP_INFINITE)
	/* Real or imaginary part is infinite.  */
	__real__ result = HUGE_VALF;
      else
	__real__ result = __nanf ("");
    }

  return result;
}
Ejemplo n.º 7
0
__complex__ float
__clogf (__complex__ float x)
{
  __complex__ float 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_PI : 0.0;
      __imag__ result = __copysignf (__imag__ result, __imag__ x);
      /* Yes, the following line raises an exception.  */
      __real__ result = -1.0 / fabsf (__real__ x);
    }
  else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1))
    {
      /* Neither real nor imaginary part is NaN.  */
      float absx = fabsf (__real__ x), absy = fabsf (__imag__ x);
      int scale = 0;

      if (absx < absy)
	{
	  float t = absx;
	  absx = absy;
	  absy = t;
	}

      if (absx > FLT_MAX / 2.0f)
	{
	  scale = -1;
	  absx = __scalbnf (absx, scale);
	  absy = (absy >= FLT_MIN * 2.0f ? __scalbnf (absy, scale) : 0.0f);
	}
      else if (absx < FLT_MIN && absy < FLT_MIN)
	{
	  scale = FLT_MANT_DIG;
	  absx = __scalbnf (absx, scale);
	  absy = __scalbnf (absy, scale);
	}

      if (absx == 1.0f && scale == 0)
	{
	  float absy2 = absy * absy;
	  if (absy2 <= FLT_MIN * 2.0f)
	    {
#if __FLT_EVAL_METHOD__ == 0
	      __real__ result = absy2 / 2.0f - absy2 * absy2 / 4.0f;
#else
	      volatile float force_underflow = absy2 * absy2 / 4.0f;
	      __real__ result = absy2 / 2.0f - force_underflow;
#endif
	    }
	  else
	    __real__ result = __log1pf (absy2) / 2.0f;
	}
      else if (absx > 1.0f && absx < 2.0f && absy < 1.0f && scale == 0)
	{
	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
	  if (absy >= FLT_EPSILON)
	    d2m1 += absy * absy;
	  __real__ result = __log1pf (d2m1) / 2.0f;
	}
      else if (absx < 1.0f
	       && absx >= 0.75f
	       && absy < FLT_EPSILON / 2.0f
	       && scale == 0)
	{
	  float d2m1 = (absx - 1.0f) * (absx + 1.0f);
	  __real__ result = __log1pf (d2m1) / 2.0f;
	}
      else if (absx < 1.0f && (absx >= 0.75f || absy >= 0.5f) && scale == 0)
	{
	  float d2m1 = __x2y2m1f (absx, absy);
	  __real__ result = __log1pf (d2m1) / 2.0f;
	}
      else
	{
	  float d = __ieee754_hypotf (absx, absy);
	  __real__ result = __ieee754_logf (d) - scale * (float) M_LN2;
	}

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

  return result;
}
Ejemplo n.º 8
0
__complex__ float
__csqrtf (__complex__ float x)
{
  __complex__ float 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_VALF;
	  __imag__ res = __imag__ x;
	}
      else if (rcls == FP_INFINITE)
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = icls == FP_NAN ? __nanf ("") : 0;
	      __imag__ res = __copysignf (HUGE_VALF, __imag__ x);
	    }
	  else
	    {
	      __real__ res = __real__ x;
	      __imag__ res = (icls == FP_NAN
			      ? __nanf ("") : __copysignf (0.0, __imag__ x));
	    }
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else
    {
      if (__builtin_expect (icls == FP_ZERO, 0))
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = 0.0;
	      __imag__ res = __copysignf (__ieee754_sqrtf (-__real__ x),
					  __imag__ x);
	    }
	  else
	    {
	      __real__ res = fabsf (__ieee754_sqrtf (__real__ x));
	      __imag__ res = __copysignf (0.0, __imag__ x);
	    }
	}
      else if (__builtin_expect (rcls == FP_ZERO, 0))
	{
	  float r;
	  if (fabsf (__imag__ x) >= 2.0f * FLT_MIN)
	    r = __ieee754_sqrtf (0.5f * fabsf (__imag__ x));
	  else
	    r = 0.5f * __ieee754_sqrtf (2.0f * fabsf (__imag__ x));

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

	  if (fabsf (__real__ x) > FLT_MAX / 4.0f)
	    {
	      scale = 1;
	      __real__ x = __scalbnf (__real__ x, -2 * scale);
	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
	    }
	  else if (fabsf (__imag__ x) > FLT_MAX / 4.0f)
	    {
	      scale = 1;
	      if (fabsf (__real__ x) >= 4.0f * FLT_MIN)
		__real__ x = __scalbnf (__real__ x, -2 * scale);
	      else
		__real__ x = 0.0f;
	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
	    }
	  else if (fabsf (__real__ x) < FLT_MIN
		   && fabsf (__imag__ x) < FLT_MIN)
	    {
	      scale = -(FLT_MANT_DIG / 2);
	      __real__ x = __scalbnf (__real__ x, -2 * scale);
	      __imag__ x = __scalbnf (__imag__ x, -2 * scale);
	    }

	  d = __ieee754_hypotf (__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_sqrtf (0.5f * (d + __real__ x));
	      s = 0.5f * (__imag__ x / r);
	    }
	  else
	    {
	      s = __ieee754_sqrtf (0.5f * (d - __real__ x));
	      r = fabsf (0.5f * (__imag__ x / s));
	    }

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

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

  return res;
}
Ejemplo n.º 9
0
__complex__ float
__catanf (__complex__ float x)
{
  __complex__ float res;
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  if (__glibc_unlikely (rcls <= FP_INFINITE || icls <= FP_INFINITE))
    {
      if (rcls == FP_INFINITE)
	{
	  __real__ res = __copysignf (M_PI_2, __real__ x);
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else if (icls == FP_INFINITE)
	{
	  if (rcls >= FP_ZERO)
	    __real__ res = __copysignf (M_PI_2, __real__ x);
	  else
	    __real__ res = __nanf ("");
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else if (icls == FP_ZERO || icls == FP_INFINITE)
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else if (__glibc_unlikely (rcls == FP_ZERO && icls == FP_ZERO))
    {
      res = x;
    }
  else
    {
      if (fabsf (__real__ x) >= 16.0f / FLT_EPSILON
	  || fabsf (__imag__ x) >= 16.0f / FLT_EPSILON)
	{
	  __real__ res = __copysignf ((float) M_PI_2, __real__ x);
	  if (fabsf (__real__ x) <= 1.0f)
	    __imag__ res = 1.0f / __imag__ x;
	  else if (fabsf (__imag__ x) <= 1.0f)
	    __imag__ res = __imag__ x / __real__ x / __real__ x;
	  else
	    {
	      float h = __ieee754_hypotf (__real__ x / 2.0f,
					  __imag__ x / 2.0f);
	      __imag__ res = __imag__ x / h / h / 4.0f;
	    }
	}
      else
	{
	  float den, absx, absy;

	  absx = fabsf (__real__ x);
	  absy = fabsf (__imag__ x);
	  if (absx < absy)
	    {
	      float t = absx;
	      absx = absy;
	      absy = t;
	    }

	  if (absy < FLT_EPSILON / 2.0f)
	    {
	      den = (1.0f - absx) * (1.0f + absx);
	      if (den == -0.0f)
		den = 0.0f;
	    }
	  else if (absx >= 1.0f)
	    den = (1.0f - absx) * (1.0f + absx) - absy * absy;
	  else if (absx >= 0.75f || absy >= 0.5f)
	    den = -__x2y2m1f (absx, absy);
	  else
	    den = (1.0f - absx) * (1.0f + absx) - absy * absy;

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

	  if (fabsf (__imag__ x) == 1.0f
	      && fabsf (__real__ x) < FLT_EPSILON * FLT_EPSILON)
	    __imag__ res = (__copysignf (0.5f, __imag__ x)
			    * ((float) M_LN2
			       - __ieee754_logf (fabsf (__real__ x))));
	  else
	    {
	      float r2 = 0.0f, num, f;

	      if (fabsf (__real__ x) >= FLT_EPSILON * FLT_EPSILON)
		r2 = __real__ x * __real__ x;

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

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

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

      if (fabsf (__real__ res) < FLT_MIN)
	{
	  volatile float force_underflow = __real__ res * __real__ res;
	  (void) force_underflow;
	}
      if (fabsf (__imag__ res) < FLT_MIN)
	{
	  volatile float force_underflow = __imag__ res * __imag__ res;
	  (void) force_underflow;
	}
    }

  return res;
}
Ejemplo n.º 10
0
__complex__ float
__kernel_casinhf (__complex__ float x, int adj)
{
  __complex__ float res;
  float rx, ix;
  __complex__ float y;

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

  if (rx >= 1.0f / FLT_EPSILON || ix >= 1.0f / FLT_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)
	{
	  float t = __real__ y;
	  __real__ y = __copysignf (__imag__ y, __imag__ x);
	  __imag__ y = t;
	}

      res = __clogf (y);
      __real__ res += (float) M_LN2;
    }
  else if (rx >= 0.5f && ix < FLT_EPSILON / 8.0f)
    {
      float s = __ieee754_hypotf (1.0f, rx);

      __real__ res = __ieee754_logf (rx + s);
      if (adj)
	__imag__ res = __ieee754_atan2f (s, __imag__ x);
      else
	__imag__ res = __ieee754_atan2f (ix, s);
    }
  else if (rx < FLT_EPSILON / 8.0f && ix >= 1.5f)
    {
      float s = __ieee754_sqrtf ((ix + 1.0f) * (ix - 1.0f));

      __real__ res = __ieee754_logf (ix + s);
      if (adj)
	__imag__ res = __ieee754_atan2f (rx, __copysignf (s, __imag__ x));
      else
	__imag__ res = __ieee754_atan2f (s, rx);
    }
  else if (ix > 1.0f && ix < 1.5f && rx < 0.5f)
    {
      if (rx < FLT_EPSILON * FLT_EPSILON)
	{
	  float ix2m1 = (ix + 1.0f) * (ix - 1.0f);
	  float s = __ieee754_sqrtf (ix2m1);

	  __real__ res = __log1pf (2.0f * (ix2m1 + ix * s)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (rx, __copysignf (s, __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (s, rx);
	}
      else
	{
	  float ix2m1 = (ix + 1.0f) * (ix - 1.0f);
	  float rx2 = rx * rx;
	  float f = rx2 * (2.0f + rx2 + 2.0f * ix * ix);
	  float d = __ieee754_sqrtf (ix2m1 * ix2m1 + f);
	  float dp = d + ix2m1;
	  float dm = f / dp;
	  float r1 = __ieee754_sqrtf ((dm + rx2) / 2.0f);
	  float r2 = rx * ix / r1;

	  __real__ res
	    = __log1pf (rx2 + dp + 2.0f * (rx * r1 + ix * r2)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (rx + r1, __copysignf (ix + r2,
								   __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (ix + r2, rx + r1);
	}
    }
  else if (ix == 1.0f && rx < 0.5f)
    {
      if (rx < FLT_EPSILON / 8.0f)
	{
	  __real__ res = __log1pf (2.0f * (rx + __ieee754_sqrtf (rx))) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (__ieee754_sqrtf (rx),
					     __copysignf (1.0f, __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (1.0f, __ieee754_sqrtf (rx));
	}
      else
	{
	  float d = rx * __ieee754_sqrtf (4.0f + rx * rx);
	  float s1 = __ieee754_sqrtf ((d + rx * rx) / 2.0f);
	  float s2 = __ieee754_sqrtf ((d - rx * rx) / 2.0f);

	  __real__ res = __log1pf (rx * rx + d + 2.0f * (rx * s1 + s2)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (rx + s1,
					     __copysignf (1.0f + s2,
							  __imag__ x));
	  else
	    __imag__ res = __ieee754_atan2f (1.0f + s2, rx + s1);
	}
    }
  else if (ix < 1.0f && rx < 0.5f)
    {
      if (ix >= FLT_EPSILON)
	{
	  if (rx < FLT_EPSILON * FLT_EPSILON)
	    {
	      float onemix2 = (1.0f + ix) * (1.0f - ix);
	      float s = __ieee754_sqrtf (onemix2);

	      __real__ res = __log1pf (2.0f * rx / s) / 2.0f;
	      if (adj)
		__imag__ res = __ieee754_atan2f (s, __imag__ x);
	      else
		__imag__ res = __ieee754_atan2f (ix, s);
	    }
	  else
	    {
	      float onemix2 = (1.0f + ix) * (1.0f - ix);
	      float rx2 = rx * rx;
	      float f = rx2 * (2.0f + rx2 + 2.0f * ix * ix);
	      float d = __ieee754_sqrtf (onemix2 * onemix2 + f);
	      float dp = d + onemix2;
	      float dm = f / dp;
	      float r1 = __ieee754_sqrtf ((dp + rx2) / 2.0f);
	      float r2 = rx * ix / r1;

	      __real__ res
		= __log1pf (rx2 + dm + 2.0f * (rx * r1 + ix * r2)) / 2.0f;
	      if (adj)
		__imag__ res = __ieee754_atan2f (rx + r1,
						 __copysignf (ix + r2,
							      __imag__ x));
	      else
		__imag__ res = __ieee754_atan2f (ix + r2, rx + r1);
	    }
	}
      else
	{
	  float s = __ieee754_hypotf (1.0f, rx);

	  __real__ res = __log1pf (2.0f * rx * (rx + s)) / 2.0f;
	  if (adj)
	    __imag__ res = __ieee754_atan2f (s, __imag__ x);
	  else
	    __imag__ res = __ieee754_atan2f (ix, s);
	}
      if (__real__ res < FLT_MIN)
	{
	  volatile float force_underflow = __real__ res * __real__ res;
	  (void) force_underflow;
	}
    }
  else
    {
      __real__ y = (rx - ix) * (rx + ix) + 1.0f;
      __imag__ y = 2.0f * rx * ix;

      y = __csqrtf (y);

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

      if (adj)
	{
	  float t = __real__ y;
	  __real__ y = __copysignf (__imag__ y, __imag__ x);
	  __imag__ y = t;
	}

      res = __clogf (y);
    }

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

  return res;
}
Ejemplo n.º 11
0
__complex__ float
__csqrtf (__complex__ float x)
{
  __complex__ float 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_VALF;
	  __imag__ res = __imag__ x;
	}
      else if (rcls == FP_INFINITE)
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = icls == FP_NAN ? __nanf ("") : 0;
	      __imag__ res = __copysignf (HUGE_VALF, __imag__ x);
	    }
	  else
	    {
	      __real__ res = __real__ x;
	      __imag__ res = (icls == FP_NAN
			      ? __nanf ("") : __copysignf (0.0, __imag__ x));
	    }
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");
	}
    }
  else
    {
      if (icls == FP_ZERO)
	{
	  if (__real__ x < 0.0)
	    {
	      __real__ res = 0.0;
	      __imag__ res = __copysignf (__ieee754_sqrtf (-__real__ x),
					  __imag__ x);
	    }
	  else
	    {
	      __real__ res = fabsf (__ieee754_sqrtf (__real__ x));
	      __imag__ res = __copysignf (0.0, __imag__ x);
	    }
	}
      else if (rcls == FP_ZERO)
	{
	  float r = __ieee754_sqrtf (0.5 * fabsf (__imag__ x));

	  __real__ res = __copysignf (r, __imag__ x);
	  __imag__ res = r;
	}
      else
	{
	  float d, r, s;

	  d = __ieee754_hypotf (__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_sqrtf (0.5f * d + 0.5f * __real__ x);
	      s = (0.5f * __imag__ x) / r;
	    }
	  else
	    {
	      s = __ieee754_sqrtf (0.5f * d - 0.5f * __real__ x);
	      r = fabsf ((0.5f * __imag__ x) / s);
	    }

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

  return res;
}