Esempio n. 1
0
float
__ieee754_sinhf(float x)
{
	float t,h;
	int32_t ix,jx;

	GET_FLOAT_WORD(jx,x);
	ix = jx&0x7fffffff;

    /* x is INF or NaN */
	if(ix>=0x7f800000) return x+x;

	h = 0.5;
	if (jx<0) h = -h;
    /* |x| in [0,9], return sign(x)*0.5*(E+E/(E+1))) */
	if (ix < 0x41100000) {		/* |x|<9 */
	    if (ix<0x39800000) 		/* |x|<2**-12 */
		if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
	    t = expm1f(fabsf(x));
	    if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one));
	    return h*(t+t/(t+one));
	}

    /* |x| in [9, logf(maxfloat)] return 0.5*exp(|x|) */
	if (ix < 0x42b17217)  return h*__ieee754_expf(fabsf(x));

    /* |x| in [logf(maxfloat), overflowthresold] */
	if (ix<=0x42b2d4fc)
	    return h*2.0F*__ldexp_expf(fabsf(x), -1);

    /* |x| > overflowthresold, sinh(x) overflow */
	return x*shuge;
}
Esempio n. 2
0
float
__ieee754_gammaf_r (float x, int *signgamp)
{
  /* We don't have a real gamma implementation now.  We'll use lgamma
     and the exp function.  But due to the required boundary
     conditions we must check some values separately.  */
  int32_t hx;

  GET_FLOAT_WORD (hx, x);

  if (__builtin_expect ((hx & 0x7fffffff) == 0, 0))
    {
      /* Return value for x == 0 is Inf with divide by zero exception.  */
      *signgamp = 0;
      return 1.0 / x;
    }
  if (__builtin_expect (hx < 0, 0)
      && (u_int32_t) hx < 0xff800000 && __rintf (x) == x)
    {
      /* Return value for integer x < 0 is NaN with invalid exception.  */
      *signgamp = 0;
      return (x - x) / (x - x);
    }
  if (__builtin_expect (hx == 0xff800000, 0))
    {
      /* x == -Inf.  According to ISO this is NaN.  */
      *signgamp = 0;
      return x - x;
    }

  /* XXX FIXME.  */
  return __ieee754_expf (__ieee754_lgammaf_r (x, signgamp));
}
Esempio n. 3
0
/* wrapper expf */
float
__expf_compat (float x)
{
  float z = __ieee754_expf (x);
  if (__builtin_expect (!isfinite (z) || z == 0, 0)
      && isfinite (x) && _LIB_VERSION != _IEEE_)
    return __kernel_standard_f (x, x, 106 + !!signbit (x));

  return z;
}
Esempio n. 4
0
float
expf(float x)		/* wrapper expf */
{
#ifdef _IEEE_LIBM
	return __ieee754_expf(x);
#else
	float z;
	z = __ieee754_expf(x);
	if(_LIB_VERSION == _IEEE_) return z;
	if(finitef(x)) {
	    if(x>o_threshold)
	        /* exp overflow */
	        return (float)__kernel_standard((double)x,(double)x,106);
	    else if(x<u_threshold)
	        /* exp underflow */
	        return (float)__kernel_standard((double)x,(double)x,107);
	}
	return z;
#endif
}
Esempio n. 5
0
float
__ieee754_coshf(float x)
{
	float t,w;
	int32_t ix;

	GET_FLOAT_WORD(ix,x);
	ix &= 0x7fffffff;

    /* x is INF or NaN */
	if(ix>=0x7f800000) return x*x;

    /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */
	if(ix<0x3eb17218) {
	    t = expm1f(fabsf(x));
	    w = one+t;
	    if (ix<0x39800000) return one;	/* cosh(tiny) = 1 */
	    return one+(t*t)/(w+w);
	}

    /* |x| in [0.5*ln2,9], return (exp(|x|)+1/exp(|x|))/2; */
	if (ix < 0x41100000) {
		t = __ieee754_expf(fabsf(x));
		return half*t+half/t;
	}

    /* |x| in [9, log(maxfloat)] return half*exp(|x|) */
	if (ix < 0x42b17217)  return half*__ieee754_expf(fabsf(x));

    /* |x| in [log(maxfloat), overflowthresold] */
	if (ix<=0x42b2d4fc) {
	    w = __ieee754_expf(half*fabsf(x));
	    t = half*w;
	    return t*w;
	}

    /* |x| > overflowthresold, cosh(x) overflow */
	return huge*huge;
}
Esempio n. 6
0
float
__ieee754_sinhf(float x)
{
	float t,w,h;
	int32_t ix,jx;

	GET_FLOAT_WORD(jx,x);
	ix = jx&0x7fffffff;

    /* x is INF or NaN */
	if(__builtin_expect(ix>=0x7f800000, 0)) return x+x;

	h = 0.5;
	if (jx<0) h = -h;
    /* |x| in [0,22], return sign(x)*0.5*(E+E/(E+1))) */
	if (ix < 0x41b00000) {		/* |x|<22 */
	    if (__builtin_expect(ix<0x31800000, 0)) {	/* |x|<2**-28 */
		math_check_force_underflow (x);
		if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */
	    }
	    t = __expm1f(fabsf(x));
	    if(ix<0x3f800000) return h*((float)2.0*t-t*t/(t+one));
	    return h*(t+t/(t+one));
	}

    /* |x| in [22, log(maxdouble)] return 0.5*exp(|x|) */
	if (ix < 0x42b17180)  return h*__ieee754_expf(fabsf(x));

    /* |x| in [log(maxdouble), overflowthresold] */
	if (ix<=0x42b2d4fc) {
	    w = __ieee754_expf((float)0.5*fabsf(x));
	    t = h*w;
	    return t*w;
	}

    /* |x| > overflowthresold, sinh(x) overflow */
	return math_narrow_eval (x*shuge);
}
Esempio n. 7
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;
}
Esempio n. 8
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;
}
Esempio n. 9
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;
}
Esempio n. 10
0
static float
gammaf_positive (float x, int *exp2_adj)
{
  int local_signgam;
  if (x < 0.5f)
    {
      *exp2_adj = 0;
      return __ieee754_expf (__ieee754_lgammaf_r (x + 1, &local_signgam)) / x;
    }
  else if (x <= 1.5f)
    {
      *exp2_adj = 0;
      return __ieee754_expf (__ieee754_lgammaf_r (x, &local_signgam));
    }
  else if (x < 2.5f)
    {
      *exp2_adj = 0;
      float x_adj = x - 1;
      return (__ieee754_expf (__ieee754_lgammaf_r (x_adj, &local_signgam))
	      * x_adj);
    }
  else
    {
      float eps = 0;
      float x_eps = 0;
      float x_adj = x;
      float prod = 1;
      if (x < 4.0f)
	{
	  /* Adjust into the range for applying Stirling's
	     approximation.  */
	  float n = __ceilf (4.0f - x);
	  x_adj = math_narrow_eval (x + n);
	  x_eps = (x - (x_adj - n));
	  prod = __gamma_productf (x_adj - n, x_eps, n, &eps);
	}
      /* The result is now gamma (X_ADJ + X_EPS) / (PROD * (1 + EPS)).
	 Compute gamma (X_ADJ + X_EPS) using Stirling's approximation,
	 starting by computing pow (X_ADJ, X_ADJ) with a power of 2
	 factored out.  */
      float exp_adj = -eps;
      float x_adj_int = __roundf (x_adj);
      float x_adj_frac = x_adj - x_adj_int;
      int x_adj_log2;
      float x_adj_mant = __frexpf (x_adj, &x_adj_log2);
      if (x_adj_mant < (float) M_SQRT1_2)
	{
	  x_adj_log2--;
	  x_adj_mant *= 2.0f;
	}
      *exp2_adj = x_adj_log2 * (int) x_adj_int;
      float ret = (__ieee754_powf (x_adj_mant, x_adj)
		   * __ieee754_exp2f (x_adj_log2 * x_adj_frac)
		   * __ieee754_expf (-x_adj)
		   * __ieee754_sqrtf (2 * (float) M_PI / x_adj)
		   / prod);
      exp_adj += x_eps * __ieee754_logf (x_adj);
      float bsum = gamma_coeff[NCOEFF - 1];
      float x_adj2 = x_adj * x_adj;
      for (size_t i = 1; i <= NCOEFF - 1; i++)
	bsum = bsum / x_adj2 + gamma_coeff[NCOEFF - 1 - i];
      exp_adj += bsum / x_adj;
      return ret + ret * __expm1f (exp_adj);
    }
}
Esempio n. 11
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;
}
Esempio n. 12
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;
}