_Float128 __tanhl (_Float128 x) { _Float128 t, z; uint32_t jx, ix; ieee854_long_double_shape_type u; /* Words of |x|. */ u.value = x; jx = u.parts32.w0; ix = jx & 0x7fffffff; /* x is INF or NaN */ if (ix >= 0x7fff0000) { /* for NaN it's not important which branch: tanhl(NaN) = NaN */ if (jx & 0x80000000) return one / x - one; /* tanhl(-inf)= -1; */ else return one / x + one; /* tanhl(+inf)=+1 */ } /* |x| < 40 */ if (ix < 0x40044000) { if (u.value == 0) return x; /* x == +- 0 */ if (ix < 0x3fc60000) /* |x| < 2^-57 */ { math_check_force_underflow (x); return x * (one + tiny); /* tanh(small) = small */ } u.parts32.w0 = ix; /* Absolute value of x. */ if (ix >= 0x3fff0000) { /* |x| >= 1 */ t = __expm1l (two * u.value); z = one - two / (t + two); } else { t = __expm1l (-two * u.value); z = -t / (t + two); } /* |x| > 40, return +-1 */ } else { z = one - tiny; /* raised inexact flag */ } return (jx & 0x80000000) ? -z : z; }
long double __tanhl(long double x) { long double t,z; int64_t jx,ix; double xhi; /* High word of |x|. */ xhi = ldbl_high (x); EXTRACT_WORDS64 (jx, xhi); ix = jx&0x7fffffffffffffffLL; /* x is INF or NaN */ if(ix>=0x7ff0000000000000LL) { if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ else return one/x-one; /* tanh(NaN) = NaN */ } /* |x| < 40 */ if (ix < 0x4044000000000000LL) { /* |x|<40 */ if (ix == 0) return x; /* x == +-0 */ if (ix<0x3c60000000000000LL) /* |x|<2**-57 */ { math_check_force_underflow (x); return x; /* tanh(small) = small */ } if (ix>=0x3ff0000000000000LL) { /* |x|>=1 */ t = __expm1l(two*fabsl(x)); z = one - two/(t+two); } else { t = __expm1l(-two*fabsl(x)); z= -t/(t+two); } /* |x| > 40, return +-1 */ } else { z = one - tiny; /* raised inexact flag */ } return (jx>=0)? z: -z; }
long double __ieee754_sinhl (long double x) { long double t, w, h; u_int32_t jx, ix; ieee854_long_double_shape_type u; /* Words of |x|. */ u.value = x; jx = u.parts32.w0; ix = jx & 0x7fffffff; /* x is INF or NaN */ if (ix >= 0x7fff0000) return x + x; h = 0.5; if (jx & 0x80000000) h = -h; /* Absolute value of x. */ u.parts32.w0 = ix; /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */ if (ix <= 0x40044000) { if (ix < 0x3fc60000) /* |x| < 2^-57 */ if (shuge + x > one) return x; /* sinh(tiny) = tiny with inexact */ t = __expm1l (u.value); if (ix < 0x3fff0000) return h * (2.0 * t - t * t / (t + one)); return h * (t + t / (t + one)); } /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */ if (ix <= 0x400c62e3) /* 11356.375 */ return h * __ieee754_expl (u.value); /* |x| in [log(maxdouble), overflowthreshold] Overflow threshold is log(2 * maxdouble). */ if (u.value <= ovf_thresh) { w = __ieee754_expl (0.5 * u.value); t = h * w; return t * w; } /* |x| > overflowthreshold, sinhl(x) overflow */ return x * shuge; }
long double __ieee754_sinhl(long double x) { long double t,w,h; u_int32_t jx,ix,i0,i1; /* Words of |x|. */ GET_LDOUBLE_WORDS(jx,i0,i1,x); ix = jx&0x7fff; /* x is INF or NaN */ if(__builtin_expect(ix==0x7fff, 0)) return x+x; h = 0.5; if (jx & 0x8000) h = -h; /* |x| in [0,25], return sign(x)*0.5*(E+E/(E+1))) */ if (ix < 0x4003 || (ix == 0x4003 && i0 <= 0xc8000000)) { /* |x|<25 */ if (ix<0x3fdf) { /* |x|<2**-32 */ if (fabsl (x) < LDBL_MIN) { long double force_underflow = x * x; math_force_eval (force_underflow); } if(shuge+x>one) return x;/* sinh(tiny) = tiny with inexact */ } t = __expm1l(fabsl(x)); if(ix<0x3fff) return h*(2.0*t-t*t/(t+one)); return h*(t+t/(t+one)); } /* |x| in [25, log(maxdouble)] return 0.5*exp(|x|) */ if (ix < 0x400c || (ix == 0x400c && i0 < 0xb17217f7)) return h*__ieee754_expl(fabsl(x)); /* |x| in [log(maxdouble), overflowthreshold] */ if (ix<0x400c || (ix == 0x400c && (i0 < 0xb174ddc0 || (i0 == 0xb174ddc0 && i1 <= 0x31aec0ea)))) { w = __ieee754_expl(0.5*fabsl(x)); t = h*w; return t*w; } /* |x| > overflowthreshold, sinhl(x) overflow */ return x*shuge; }
long double __ieee754_sinhl(long double x) { long double t,w,h; int64_t ix,jx; double xhi; /* High word of |x|. */ xhi = ldbl_high (x); EXTRACT_WORDS64 (jx, xhi); ix = jx&0x7fffffffffffffffLL; /* x is INF or NaN */ if(ix>=0x7ff0000000000000LL) return x+x; h = 0.5; if (jx<0) h = -h; /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */ if (ix < 0x4044000000000000LL) { /* |x|<40 */ if (ix<0x3c90000000000000LL) { /* |x|<2**-54 */ math_check_force_underflow (x); if(shuge+x>one) return x;/* sinhl(tiny) = tiny with inexact */ } t = __expm1l(fabsl(x)); if(ix<0x3ff0000000000000LL) return h*(2.0*t-t*t/(t+one)); w = t/(t+one); return h*(t+w); } /* |x| in [40, log(maxdouble)] return 0.5*exp(|x|) */ if (ix < 0x40862e42fefa39efLL) return h*__ieee754_expl(fabsl(x)); /* |x| in [log(maxdouble), overflowthresold] */ if (ix <= 0x408633ce8fb9f87eLL) { w = __ieee754_expl(0.5*fabsl(x)); t = h*w; return t*w; } /* |x| > overflowthresold, sinh(x) overflow */ return x*shuge; }
long double __ieee754_coshl (long double x) { long double t,w; int64_t ix; /* High word of |x|. */ GET_LDOUBLE_MSW64(ix,x); ix &= 0x7fffffffffffffffLL; /* x is INF or NaN */ if(ix>=0x7ff0000000000000LL) return x*x; /* |x| in [0,0.5*ln2], return 1+expm1(|x|)^2/(2*exp(|x|)) */ if(ix<0x3fd62e42fefa39efLL) { t = __expm1l(fabsl(x)); w = one+t; if (ix<0x3c80000000000000LL) return w; /* cosh(tiny) = 1 */ return one+(t*t)/(w+w); } /* |x| in [0.5*ln2,22], return (exp(|x|)+1/exp(|x|)/2; */ if (ix < 0x4036000000000000LL) { t = __ieee754_expl(fabsl(x)); return half*t+half/t; } /* |x| in [22, log(maxdouble)] return half*exp(|x|) */ if (ix < 0x40862e42fefa39efLL) return half*__ieee754_expl(fabsl(x)); /* |x| in [log(maxdouble), overflowthresold] */ if (ix < 0x408633ce8fb9f87dLL) { w = __ieee754_expl(half*fabsl(x)); t = half*w; return t*w; } /* |x| > overflowthresold, cosh(x) overflow */ return huge*huge; }
static long double gammal_positive (long double x, int *exp2_adj) { int local_signgam; if (x < 0.5L) { *exp2_adj = 0; return __ieee754_expl (__ieee754_lgammal_r (x + 1, &local_signgam)) / x; } else if (x <= 1.5L) { *exp2_adj = 0; return __ieee754_expl (__ieee754_lgammal_r (x, &local_signgam)); } else if (x < 12.5L) { /* Adjust into the range for using exp (lgamma). */ *exp2_adj = 0; long double n = __ceill (x - 1.5L); long double x_adj = x - n; long double eps; long double prod = __gamma_productl (x_adj, 0, n, &eps); return (__ieee754_expl (__ieee754_lgammal_r (x_adj, &local_signgam)) * prod * (1.0L + eps)); } else { long double eps = 0; long double x_eps = 0; long double x_adj = x; long double prod = 1; if (x < 24.0L) { /* Adjust into the range for applying Stirling's approximation. */ long double n = __ceill (24.0L - x); x_adj = x + n; x_eps = (x - (x_adj - n)); prod = __gamma_productl (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. */ long double exp_adj = -eps; long double x_adj_int = __roundl (x_adj); long double x_adj_frac = x_adj - x_adj_int; int x_adj_log2; long double x_adj_mant = __frexpl (x_adj, &x_adj_log2); if (x_adj_mant < M_SQRT1_2l) { x_adj_log2--; x_adj_mant *= 2.0L; } *exp2_adj = x_adj_log2 * (int) x_adj_int; long double ret = (__ieee754_powl (x_adj_mant, x_adj) * __ieee754_exp2l (x_adj_log2 * x_adj_frac) * __ieee754_expl (-x_adj) * __ieee754_sqrtl (2 * M_PIl / x_adj) / prod); exp_adj += x_eps * __ieee754_logl (x_adj); long double bsum = gamma_coeff[NCOEFF - 1]; long double 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 * __expm1l (exp_adj); } }