__float128 tanhq (__float128 x) { __float128 t, z; uint32_t jx, ix; ieee854_float128 u; /* Words of |x|. */ u.value = x; jx = u.words32.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.words32.w0 = ix; /* Absolute value of x. */ if (ix >= 0x3fff0000) { /* |x| >= 1 */ t = expm1q (two * u.value); z = one - two / (t + two); } else { t = expm1q (-two * u.value); z = -t / (t + two); } /* |x| > 40, return +-1 */ } else { z = one - tiny; /* raised inexact flag */ } return (jx & 0x80000000) ? -z : z; }
__float128 sinhq (__float128 x) { __float128 t, w, h; uint32_t jx, ix; ieee854_float128 u; /* Words of |x|. */ u.value = x; jx = u.words32.w0; ix = jx & 0x7fffffff; /* x is INF or NaN */ if (ix >= 0x7fff0000) return x + x; h = 0.5Q; if (jx & 0x80000000) h = -h; /* Absolute value of x. */ u.words32.w0 = ix; /* |x| in [0,40], return sign(x)*0.5*(E+E/(E+1))) */ if (ix <= 0x40044000) { if (ix < 0x3fc60000) /* |x| < 2^-57 */ { math_check_force_underflow (x); if (shuge + x > one) return x; /* sinh(tiny) = tiny with inexact */ } t = expm1q (u.value); if (ix < 0x3fff0000) return h * (2.0Q * 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 * expq (u.value); /* |x| in [log(maxdouble), overflowthreshold] Overflow threshold is log(2 * maxdouble). */ if (u.value <= ovf_thresh) { w = expq (0.5Q * u.value); t = h * w; return t * w; } /* |x| > overflowthreshold, sinhq(x) overflow */ return x * shuge; }
__float128 coshq (__float128 x) { __float128 t, w; int32_t ex; ieee854_float128 u; u.value = x; ex = u.words32.w0 & 0x7fffffff; /* Absolute value of x. */ u.words32.w0 = ex; /* x is INF or NaN */ if (ex >= 0x7fff0000) return x * x; /* |x| in [0,0.5*ln2], return 1+expm1l(|x|)^2/(2*expq(|x|)) */ if (ex < 0x3ffd62e4) /* 0.3465728759765625 */ { t = expm1q (u.value); w = one + t; if (ex < 0x3fb80000) /* |x| < 2^-116 */ return w; /* cosh(tiny) = 1 */ return one + (t * t) / (w + w); } /* |x| in [0.5*ln2,40], return (exp(|x|)+1/exp(|x|)/2; */ if (ex < 0x40044000) { t = expq (u.value); return half * t + half / t; } /* |x| in [22, ln(maxdouble)] return half*exp(|x|) */ if (ex <= 0x400c62e3) /* 11356.375 */ return half * expq (u.value); /* |x| in [log(maxdouble), overflowthresold] */ if (u.value <= ovf_thresh) { w = expq (half * u.value); t = half * w; return t * w; } /* |x| > overflowthresold, cosh(x) overflow */ return huge * huge; }