Exemple #1
0
void SinCos(float angle, float& sin, float& cos)
{
    float angleRadians = angle * M_DEGTORAD;
#if defined(HAVE_SINCOSF)
    sincosf(angleRadians, &sin, &cos);
#elif defined(HAVE_UNDERSCORE_SINCOSF)
    __sincosf(angleRadians, &sin, &cos);
#else
    sin = sinf(angleRadians);
    cos = cosf(angleRadians);
#endif
}
Exemple #2
0
float
__ieee754_y1f(float x)
{
	float z, s,c,ss,cc,u,v;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = 0x7fffffff&hx;
    /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */
	if(__builtin_expect(ix>=0x7f800000, 0)) return  one/(x+x*x);
	if(__builtin_expect(ix==0, 0))
		return -HUGE_VALF+x;  /* -inf and overflow exception.  */
	if(__builtin_expect(hx<0, 0)) return zero/(zero*x);
	if(ix >= 0x40000000) {  /* |x| >= 2.0 */
		SET_RESTORE_ROUNDF (FE_TONEAREST);
		__sincosf (x, &s, &c);
		ss = -s-c;
		cc = s-c;
		if(ix<0x7f000000) {  /* make sure x+x not overflow */
		    z = __cosf(x+x);
		    if ((s*c)>zero) cc = z/ss;
		    else            ss = z/cc;
		}
	/* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0))
	 * where x0 = x-3pi/4
	 *      Better formula:
	 *              cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4)
	 *                      =  1/sqrt(2) * (sin(x) - cos(x))
	 *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
	 *                      = -1/sqrt(2) * (cos(x) + sin(x))
	 * To avoid cancellation, use
	 *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
	 * to compute the worse one.
	 */
		if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x);
		else {
		    u = ponef(x); v = qonef(x);
		    z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x);
		}
		return z;
	}
	if(__builtin_expect(ix<=0x33000000, 0)) {    /* x < 2**-25 */
	    z = -tpi / x;
	    if (__isinff (z))
		__set_errno (ERANGE);
	    return z;
	}
	z = x*x;
	u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4])));
	v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
	return(x*(u/v) + tpi*(__ieee754_j1f(x)*__ieee754_logf(x)-one/x));
}
Exemple #3
0
float
__ieee754_y0f(float x)
{
	float z, s,c,ss,cc,u,v;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = 0x7fffffff&hx;
    /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf.  */
	if(ix>=0x7f800000) return  one/(x+x*x);
	if(ix==0) return -HUGE_VALF+x;  /* -inf and overflow exception.  */
	if(hx<0) return zero/(zero*x);
	if(ix >= 0x40000000) {  /* |x| >= 2.0 */
	/* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0))
	 * where x0 = x-pi/4
	 *      Better formula:
	 *              cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4)
	 *                      =  1/sqrt(2) * (sin(x) + cos(x))
	 *              sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4)
	 *                      =  1/sqrt(2) * (sin(x) - cos(x))
	 * To avoid cancellation, use
	 *              sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x))
	 * to compute the worse one.
	 */
		__sincosf (x, &s, &c);
		ss = s-c;
		cc = s+c;
	/*
	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
	 */
		if(ix<0x7f000000) {  /* make sure x+x not overflow */
		    z = -__cosf(x+x);
		    if ((s*c)<zero) cc = z/ss;
		    else            ss = z/cc;
		}
		if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x);
		else {
		    u = pzerof(x); v = qzerof(x);
		    z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x);
		}
		return z;
	}
	if(ix<=0x32000000) {	/* x < 2**-27 */
	    return(u00 + tpi*__ieee754_logf(x));
	}
	z = x*x;
	u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06)))));
	v = one+z*(v01+z*(v02+z*(v03+z*v04)));
	return(u/v + tpi*(__ieee754_j0f(x)*__ieee754_logf(x)));
}
__device__ void single_precision_intrinsics()
{
    float fX, fY;

    __cosf(0.0f);
    __exp10f(0.0f);
    __expf(0.0f);
    __fadd_rd(0.0f, 1.0f);
    __fadd_rn(0.0f, 1.0f);
    __fadd_ru(0.0f, 1.0f);
    __fadd_rz(0.0f, 1.0f);
    __fdiv_rd(4.0f, 2.0f);
    __fdiv_rn(4.0f, 2.0f);
    __fdiv_ru(4.0f, 2.0f);
    __fdiv_rz(4.0f, 2.0f);
    __fdividef(4.0f, 2.0f);
    __fmaf_rd(1.0f, 2.0f, 3.0f);
    __fmaf_rn(1.0f, 2.0f, 3.0f);
    __fmaf_ru(1.0f, 2.0f, 3.0f);
    __fmaf_rz(1.0f, 2.0f, 3.0f);
    __fmul_rd(1.0f, 2.0f);
    __fmul_rn(1.0f, 2.0f);
    __fmul_ru(1.0f, 2.0f);
    __fmul_rz(1.0f, 2.0f);
    __frcp_rd(2.0f);
    __frcp_rn(2.0f);
    __frcp_ru(2.0f);
    __frcp_rz(2.0f);
    __frsqrt_rn(4.0f);
    __fsqrt_rd(4.0f);
    __fsqrt_rn(4.0f);
    __fsqrt_ru(4.0f);
    __fsqrt_rz(4.0f);
    __fsub_rd(2.0f, 1.0f);
    __fsub_rn(2.0f, 1.0f);
    __fsub_ru(2.0f, 1.0f);
    __fsub_rz(2.0f, 1.0f);
    __log10f(1.0f);
    __log2f(1.0f);
    __logf(1.0f);
    __powf(1.0f, 0.0f);
    __saturatef(0.1f);
    __sincosf(0.0f, &fX, &fY);
    __sinf(0.0f);
    __tanf(0.0f);
}
Exemple #5
0
float
__ieee754_j0f(float x)
{
	float z, s,c,ss,cc,r,u,v;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix>=0x7f800000) return one/(x*x);
	x = fabsf(x);
	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
		__sincosf (x, &s, &c);
		ss = s-c;
		cc = s+c;
		if(ix<0x7f000000) {  /* make sure x+x not overflow */
		    z = -__cosf(x+x);
		    if ((s*c)<zero) cc = z/ss;
		    else	    ss = z/cc;
		}
	/*
	 * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x)
	 * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x)
	 */
		if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(x);
		else {
		    u = pzerof(x); v = qzerof(x);
		    z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(x);
		}
		return z;
	}
	if(ix<0x39000000) {	/* |x| < 2**-13 */
	    math_force_eval(huge+x);		/* raise inexact if x != 0 */
	    if(ix<0x32000000) return one;	/* |x|<2**-27 */
	    else	      return one - (float)0.25*x*x;
	}
	z = x*x;
	r =  z*(R02+z*(R03+z*(R04+z*R05)));
	s =  one+z*(S01+z*(S02+z*(S03+z*S04)));
	if(ix < 0x3F800000) {	/* |x| < 1.00 */
	    return one + z*((float)-0.25+(r/s));
	} else {
	    u = (float)0.5*x;
	    return((one+u)*(one-u)+z*(r/s));
	}
}
Exemple #6
0
__complex__ float
__ctanf (__complex__ float x)
{
  __complex__ float res;

  if (!isfinite (__real__ x) || !isfinite (__imag__ x))
    {
      if (__isinff (__imag__ x))
	{
	  __real__ res = __copysignf (0.0, __real__ x);
	  __imag__ res = __copysignf (1.0, __imag__ x);
	}
      else if (__real__ x == 0.0)
	{
	  res = x;
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");

#ifdef FE_INVALID
	  if (__isinff (__real__ x))
	    feraiseexcept (FE_INVALID);
#endif
	}
    }
  else
    {
      float sin2rx, cos2rx;
      float den;

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

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

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

  return res;
}
Exemple #7
0
float
__ieee754_j1f(float x)
{
	float z, s,c,ss,cc,r,u,v,y;
	int32_t hx,ix;

	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(__builtin_expect(ix>=0x7f800000, 0)) return one/x;
	y = fabsf(x);
	if(ix >= 0x40000000) {	/* |x| >= 2.0 */
		__sincosf (y, &s, &c);
		ss = -s-c;
		cc = s-c;
		if(ix<0x7f000000) {  /* make sure y+y not overflow */
		    z = __cosf(y+y);
		    if ((s*c)>zero) cc = z/ss;
		    else	    ss = z/cc;
		}
	/*
	 * j1(x) = 1/sqrt(pi) * (P(1,x)*cc - Q(1,x)*ss) / sqrt(x)
	 * y1(x) = 1/sqrt(pi) * (P(1,x)*ss + Q(1,x)*cc) / sqrt(x)
	 */
		if(ix>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(y);
		else {
		    u = ponef(y); v = qonef(y);
		    z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(y);
		}
		if(hx<0) return -z;
		else	 return  z;
	}
	if(__builtin_expect(ix<0x32000000, 0)) {	/* |x|<2**-27 */
	    if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */
	}
	z = x*x;
	r =  z*(r00+z*(r01+z*(r02+z*r03)));
	s =  one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05))));
	r *= x;
	return(x*(float)0.5+r/s);
}
__complex__ float
__csinhf (__complex__ float x)
{
  __complex__ float retval;
  int negate = signbit (__real__ x);
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  __real__ x = fabsf (__real__ x);

  if (rcls >= FP_ZERO)
    {
      /* Real part is finite.  */
      if (icls >= FP_ZERO)
	{
	  /* Imaginary part is finite.  */
	  float sinh_val = __ieee754_sinhf (__real__ x);
	  float cosh_val = __ieee754_coshf (__real__ x);
	  float sinix, cosix;

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

	  __real__ retval = sinh_val * cosix;
	  __imag__ retval = cosh_val * sinix;

	  if (negate)
	    __real__ retval = -__real__ retval;
	}
      else
	{
	  if (rcls == FP_ZERO)
	    {
	      /* Real part is 0.0.  */
	      __real__ retval = __copysignf (0.0, negate ? -1.0 : 1.0);
	      __imag__ retval = __nanf ("") + __nanf ("");

#ifdef FE_INVALID
	      if (icls == FP_INFINITE)
		feraiseexcept (FE_INVALID);
#endif
	    }
	  else
	    {
	      __real__ retval = __nanf ("");
	      __imag__ retval = __nanf ("");

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

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

	  __real__ retval = __copysignf (HUGE_VALF, cosix);
	  __imag__ retval = __copysignf (HUGE_VALF, sinix);

	  if (negate)
	    __real__ retval = -__real__ retval;
	}
      else
	{
	  /* The addition raises the invalid exception.  */
	  __real__ retval = HUGE_VALF;
	  __imag__ retval = __nanf ("") + __nanf ("");

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

  return retval;
}
Exemple #9
0
__complex__ float
__csinhf (__complex__ float x)
{
  __complex__ float retval;
  int negate = signbit (__real__ x);
  int rcls = fpclassify (__real__ x);
  int icls = fpclassify (__imag__ x);

  __real__ x = fabsf (__real__ 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) ((FLT_MAX_EXP - 1) * M_LN2);
	  float sinix, cosix;

	  if (__builtin_expect (icls != FP_SUBNORMAL, 1))
	    {
	      __sincosf (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0f;
	    }

	  if (fabsf (__real__ x) > t)
	    {
	      float exp_t = __ieee754_expf (t);
	      float rx = fabsf (__real__ x);
	      if (signbit (__real__ x))
		cosix = -cosix;
	      rx -= t;
	      sinix *= exp_t / 2.0f;
	      cosix *= exp_t / 2.0f;
	      if (rx > t)
		{
		  rx -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	      if (rx > t)
		{
		  /* Overflow (original real part of x > 3t).  */
		  __real__ retval = FLT_MAX * cosix;
		  __imag__ retval = FLT_MAX * sinix;
		}
	      else
		{
		  float exp_val = __ieee754_expf (rx);
		  __real__ retval = exp_val * cosix;
		  __imag__ retval = exp_val * sinix;
		}
	    }
	  else
	    {
	      __real__ retval = __ieee754_sinhf (__real__ x) * cosix;
	      __imag__ retval = __ieee754_coshf (__real__ x) * sinix;
	    }

	  if (negate)
	    __real__ retval = -__real__ retval;

	  if (fabsf (__real__ retval) < FLT_MIN)
	    {
	      volatile float force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabsf (__imag__ retval) < FLT_MIN)
	    {
	      volatile float force_underflow
		= __imag__ retval * __imag__ retval;
	      (void) force_underflow;
	    }
	}
      else
	{
	  if (rcls == FP_ZERO)
	    {
	      /* Real part is 0.0.  */
	      __real__ retval = __copysignf (0.0, negate ? -1.0 : 1.0);
	      __imag__ retval = __nanf ("") + __nanf ("");

	      if (icls == FP_INFINITE)
		feraiseexcept (FE_INVALID);
	    }
	  else
	    {
	      __real__ retval = __nanf ("");
	      __imag__ retval = __nanf ("");

	      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.  */
	  float sinix, cosix;

	  if (__builtin_expect (icls != FP_SUBNORMAL, 1))
	    {
	      __sincosf (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0f;
	    }

	  __real__ retval = __copysignf (HUGE_VALF, cosix);
	  __imag__ retval = __copysignf (HUGE_VALF, sinix);

	  if (negate)
	    __real__ retval = -__real__ retval;
	}
      else if (icls == FP_ZERO)
	{
	  /* Imaginary part is 0.0.  */
	  __real__ retval = negate ? -HUGE_VALF : HUGE_VALF;
	  __imag__ retval = __imag__ x;
	}
      else
	{
	  /* The addition raises the invalid exception.  */
	  __real__ retval = HUGE_VALF;
	  __imag__ retval = __nanf ("") + __nanf ("");

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

  return retval;
}
Exemple #10
0
__complex__ float
__ctanf (__complex__ float x)
{
  __complex__ float res;

  if (__glibc_unlikely (!isfinite (__real__ x) || !isfinite (__imag__ x)))
    {
      if (isinf (__imag__ x))
	{
	  if (isfinite (__real__ x) && fabsf (__real__ x) > 1.0f)
	    {
	      float sinrx, cosrx;
	      __sincosf (__real__ x, &sinrx, &cosrx);
	      __real__ res = __copysignf (0.0f, sinrx * cosrx);
	    }
	  else
	    __real__ res = __copysignf (0.0, __real__ x);
	  __imag__ res = __copysignf (1.0, __imag__ x);
	}
      else if (__real__ x == 0.0)
	{
	  res = x;
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");

	  if (isinf (__real__ x))
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      float sinrx, cosrx;
      float den;
      const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2 / 2);

      /* 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 (__glibc_likely (fabsf (__real__ x) > FLT_MIN))
	{
	  __sincosf (__real__ x, &sinrx, &cosrx);
	}
      else
	{
	  sinrx = __real__ x;
	  cosrx = 1.0f;
	}

      if (fabsf (__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).  */
	  float exp_2t = __ieee754_expf (2 * t);

	  __imag__ res = __copysignf (1.0, __imag__ x);
	  __real__ res = 4 * sinrx * cosrx;
	  __imag__ x = fabsf (__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_expf (2 * __imag__ x);
	}
      else
	{
	  float sinhix, coshix;
	  if (fabsf (__imag__ x) > FLT_MIN)
	    {
	      sinhix = __ieee754_sinhf (__imag__ x);
	      coshix = __ieee754_coshf (__imag__ x);
	    }
	  else
	    {
	      sinhix = __imag__ x;
	      coshix = 1.0f;
	    }

	  if (fabsf (sinhix) > fabsf (cosrx) * FLT_EPSILON)
	    den = cosrx * cosrx + sinhix * sinhix;
	  else
	    den = cosrx * cosrx;
	  __real__ res = sinrx * cosrx / den;
	  __imag__ res = sinhix * coshix / den;
	}
      math_check_force_underflow_complex (res);
    }

  return res;
}
Exemple #11
0
__complex__ float
__cexpf (__complex__ float x)
{
  __complex__ float 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) ((FLT_MAX_EXP - 1) * M_LN2);
	  float sinix, cosix;

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

	  if (__real__ x > t)
	    {
	      float exp_t = __ieee754_expf (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 = FLT_MAX * cosix;
	      __imag__ retval = FLT_MAX * sinix;
	    }
	  else
	    {
	      float exp_val = __ieee754_expf (__real__ x);
	      __real__ retval = exp_val * cosix;
	      __imag__ retval = exp_val * sinix;
	    }
	  if (fabsf (__real__ retval) < FLT_MIN)
	    {
	      volatile float force_underflow
		= __real__ retval * __real__ retval;
	      (void) force_underflow;
	    }
	  if (fabsf (__imag__ retval) < FLT_MIN)
	    {
	      volatile float 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 = __nanf ("");
	  __imag__ retval = __nanf ("");

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

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

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

	      __real__ retval = __copysignf (value, cosix);
	      __imag__ retval = __copysignf (value, sinix);
	    }
	}
      else if (signbit (__real__ x) == 0)
	{
	  __real__ retval = HUGE_VALF;
	  __imag__ retval = __nanf ("");

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

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

  return retval;
}
Exemple #12
0
__complex__ float
__ccoshf (__complex__ float x)
{
  __complex__ float 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) ((FLT_MAX_EXP - 1) * M_LN2);
	  float sinix, cosix;

	  if (__glibc_likely (fabsf (__imag__ x) > FLT_MIN))
	    {
	      __sincosf (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0f;
	    }

	  if (fabsf (__real__ x) > t)
	    {
	      float exp_t = __ieee754_expf (t);
	      float rx = fabsf (__real__ x);
	      if (signbit (__real__ x))
		sinix = -sinix;
	      rx -= t;
	      sinix *= exp_t / 2.0f;
	      cosix *= exp_t / 2.0f;
	      if (rx > t)
		{
		  rx -= t;
		  sinix *= exp_t;
		  cosix *= exp_t;
		}
	      if (rx > t)
		{
		  /* Overflow (original real part of x > 3t).  */
		  __real__ retval = FLT_MAX * cosix;
		  __imag__ retval = FLT_MAX * sinix;
		}
	      else
		{
		  float exp_val = __ieee754_expf (rx);
		  __real__ retval = exp_val * cosix;
		  __imag__ retval = exp_val * sinix;
		}
	    }
	  else
	    {
	      __real__ retval = __ieee754_coshf (__real__ x) * cosix;
	      __imag__ retval = __ieee754_sinhf (__real__ x) * sinix;
	    }

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

	  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.  */
	  float sinix, cosix;

	  if (__glibc_likely (fabsf (__imag__ x) > FLT_MIN))
	    {
	      __sincosf (__imag__ x, &sinix, &cosix);
	    }
	  else
	    {
	      sinix = __imag__ x;
	      cosix = 1.0f;
	    }

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

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

  return retval;
}
Exemple #13
0
__complex__ float
__ctanhf (__complex__ float x)
{
  __complex__ float res;

  if (__builtin_expect (!isfinite (__real__ x) || !isfinite (__imag__ x), 0))
    {
      if (__isinf_nsf (__real__ x))
	{
	  __real__ res = __copysignf (1.0, __real__ x);
	  __imag__ res = __copysignf (0.0, __imag__ x);
	}
      else if (__imag__ x == 0.0)
	{
	  res = x;
	}
      else
	{
	  __real__ res = __nanf ("");
	  __imag__ res = __nanf ("");

	  if (__isinf_nsf (__imag__ x))
	    feraiseexcept (FE_INVALID);
	}
    }
  else
    {
      float sinix, cosix;
      float den;
      const int t = (int) ((FLT_MAX_EXP - 1) * M_LN2 / 2);

      /* 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 (fpclassify(__imag__ x) != FP_SUBNORMAL, 1))
	{
	  __sincosf (__imag__ x, &sinix, &cosix);
	}
      else
	{
	  sinix = __imag__ x;
	  cosix = 1.0f;
	}

      if (fabsf (__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).  */
	  float exp_2t = __ieee754_expf (2 * t);

	  __real__ res = __copysignf (1.0, __real__ x);
	  __imag__ res = 4 * sinix * cosix;
	  __real__ x = fabsf (__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_expf (2 * __real__ x);
	}
      else
	{
	  float sinhrx, coshrx;
	  if (fabsf (__real__ x) > FLT_MIN)
	    {
	      sinhrx = __ieee754_sinhf (__real__ x);
	      coshrx = __ieee754_coshf (__real__ x);
	    }
	  else
	    {
	      sinhrx = __real__ x;
	      coshrx = 1.0f;
	    }

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

  return res;
}