long double __asinhl(long double x) { long double t,w; int64_t hx,ix; double xhi; xhi = ldbl_high (x); EXTRACT_WORDS64 (hx, xhi); ix = hx&0x7fffffffffffffffLL; if(ix>=0x7ff0000000000000LL) return x+x; /* x is inf or NaN */ if(ix< 0x3c70000000000000LL) { /* |x|<2**-56 */ math_check_force_underflow (x); if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x4370000000000000LL) { /* |x| > 2**56 */ w = __ieee754_logl(fabsl(x))+ln2; } else if (ix>0x4000000000000000LL) { /* 2**56 >= |x| > 2.0 */ t = fabs(x); w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t)); } else { /* 2.0 >= |x| >= 2**-56 */ t = x*x; w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t))); } if(hx>0) return w; else return -w; }
long double __ieee754_acoshl(long double x) { long double t; int64_t hx; uint64_t lx; double xhi, xlo; ldbl_unpack (x, &xhi, &xlo); EXTRACT_WORDS64 (hx, xhi); EXTRACT_WORDS64 (lx, xlo); if(hx<0x3ff0000000000000LL) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x41b0000000000000LL) { /* x > 2**28 */ if(hx >=0x7ff0000000000000LL) { /* x is inf of NaN */ return x+x; } else return __ieee754_logl(x)+ln2; /* acosh(huge)=log(2x) */ } else if (((hx-0x3ff0000000000000LL)|(lx&0x7fffffffffffffffLL))==0) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x4000000000000000LL) { /* 2**28 > x > 2 */ t=x*x; return __ieee754_logl(2.0*x-one/(x+__ieee754_sqrtl(t-one))); } else { /* 1<x<2 */ t = x-one; return __log1pl(t+__ieee754_sqrtl(2.0*t+t*t)); } }
long double sqrtl(long double x) /* wrapper sqrtl */ { #ifdef _IEEE_LIBM return __ieee754_sqrtl(x); #else long double z; z = __ieee754_sqrtl(x); if(_LIB_VERSION == _IEEE_ || isnan(x)) return z; if(x<0.0) { return __kernel_standard(x,x,226); /* sqrtl(negative) */ } else return z; #endif }
/* wrapper sqrtl */ long double __sqrtl (long double x) { if (__builtin_expect (x < 0.0L, 0) && _LIB_VERSION != _IEEE_) return __kernel_standard (x, x, 226); /* sqrt(negative) */ return __ieee754_sqrtl (x); }
long double __asinhl(long double x) { long double t,w; int64_t hx,ix; GET_LDOUBLE_MSW64(hx,x); ix = hx&0x7fffffffffffffffLL; if(ix>=0x7ff0000000000000LL) return x+x; /* x is inf or NaN */ if(ix< 0x3e20000000000000LL) { /* |x|<2**-29 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x41b0000000000000LL) { /* |x| > 2**28 */ w = __ieee754_logl(fabs(x))+ln2; } else if (ix>0x4000000000000000LL) { /* 2**28 > |x| > 2.0 */ t = fabs(x); w = __ieee754_logl(2.0*t+one/(__ieee754_sqrtl(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-29 */ t = x*x; w =__log1pl(fabsl(x)+t/(one+__ieee754_sqrtl(one+t))); } if(hx>0) return w; else return -w; }
long double __ieee754_acoshl(long double x) { long double t; u_int64_t lx; int64_t hx; GET_LDOUBLE_WORDS64(hx,lx,x); if(hx<0x3fff000000000000LL) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x4035000000000000LL) { /* x > 2**54 */ if(hx >=0x7fff000000000000LL) { /* x is inf of NaN */ return x+x; } else return __ieee754_logl(x)+ln2; /* acoshl(huge)=logl(2x) */ } else if(((hx-0x3fff000000000000LL)|lx)==0) { return 0.0L; /* acosh(1) = 0 */ } else if (hx > 0x4000000000000000LL) { /* 2**28 > x > 2 */ t=x*x; return __ieee754_logl(2.0L*x-one/(x+__ieee754_sqrtl(t-one))); } else { /* 1<x<2 */ t = x-one; return __log1pl(t+__sqrtl(2.0L*t+t*t)); } }
long double __ieee754_asinl (long double x) { long double t, w, p, q, c, r, s; int32_t ix, sign, flag; ieee854_long_double_shape_type u; flag = 0; u.value = x; sign = u.parts32.w0; ix = sign & 0x7fffffff; u.parts32.w0 = ix; /* |x| */ if (ix >= 0x3fff0000) /* |x|>= 1 */ { if (ix == 0x3fff0000 && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0) /* asin(1)=+-pi/2 with inexact */ return x * pio2_hi + x * pio2_lo; return (x - x) / (x - x); /* asin(|x|>1) is NaN */ } else if (ix < 0x3ffe0000) /* |x| < 0.5 */ { if (ix < 0x3fc60000) /* |x| < 2**-57 */ { if (huge + x > one) return x; /* return x with inexact if x!=0 */ } else { t = x * x; /* Mark to use pS, qS later on. */ flag = 1; } } else if (ix < 0x3ffe4000) /* 0.625 */ { t = u.value - 0.5625; p = ((((((((((rS10 * t + rS9) * t + rS8) * t + rS7) * t + rS6) * t + rS5) * t + rS4) * t + rS3) * t + rS2) * t + rS1) * t + rS0) * t; q = ((((((((( t + sS9) * t + sS8) * t + sS7) * t + sS6) * t + sS5) * t + sS4) * t + sS3) * t + sS2) * t + sS1) * t + sS0; t = asinr5625 + p / q; if ((sign & 0x80000000) == 0) return t; else return -t; } else { /* 1 > |x| >= 0.625 */ w = one - u.value; t = w * 0.5; } p = (((((((((pS9 * t + pS8) * t + pS7) * t + pS6) * t + pS5) * t + pS4) * t + pS3) * t + pS2) * t + pS1) * t + pS0) * t; q = (((((((( t + qS8) * t + qS7) * t + qS6) * t + qS5) * t + qS4) * t + qS3) * t + qS2) * t + qS1) * t + qS0; if (flag) /* 2^-57 < |x| < 0.5 */ { w = p / q; return x + x * w; } s = __ieee754_sqrtl (t); if (ix >= 0x3ffef333) /* |x| > 0.975 */ { w = p / q; t = pio2_hi - (2.0 * (s + s * w) - pio2_lo); } else { u.value = s; u.parts32.w3 = 0; u.parts32.w2 = 0; w = u.value; c = (t - w * w) / (s + w); r = p / q; p = 2.0 * s * r - (pio2_lo - 2.0 * c); q = pio4_hi - 2.0 * w; t = pio4_hi - (p - q); } if ((sign & 0x80000000) == 0) return t; else return -t; }
long double __ieee754_y1l (long double x) { long double xx, xinv, z, p, q, c, s, cc, ss; if (! __finitel (x)) { if (x != x) return x; else return 0.0L; } if (x <= 0.0L) { if (x < 0.0L) return (zero / (zero * x)); return -HUGE_VALL + x; } xx = fabsl (x); if (xx <= 2.0L) { /* 0 <= x <= 2 */ z = xx * xx; p = xx * neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D); p = -TWOOPI / xx + p; p = TWOOPI * __ieee754_logl (x) * __ieee754_j1l (x) + p; return p; } xinv = 1.0L / xx; z = xinv * xinv; if (xinv <= 0.25) { if (xinv <= 0.125) { if (xinv <= 0.0625) { p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID); q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID); } else { p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D); q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D); } } else if (xinv <= 0.1875) { p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D); q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D); } else { p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D); q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D); } } /* .25 */ else /* if (xinv <= 0.5) */ { if (xinv <= 0.375) { if (xinv <= 0.3125) { p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D); q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D); } else { p = neval (z, P2r7_3r2N, NP2r7_3r2N) / deval (z, P2r7_3r2D, NP2r7_3r2D); q = neval (z, Q2r7_3r2N, NQ2r7_3r2N) / deval (z, Q2r7_3r2D, NQ2r7_3r2D); } } else if (xinv <= 0.4375) { p = neval (z, P2r3_2r7N, NP2r3_2r7N) / deval (z, P2r3_2r7D, NP2r3_2r7D); q = neval (z, Q2r3_2r7N, NQ2r3_2r7N) / deval (z, Q2r3_2r7D, NQ2r3_2r7D); } else { p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D); q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D); } } p = 1.0L + z * p; q = z * q; q = q * xinv + 0.375L * xinv; /* X = x - 3 pi/4 cos(X) = cos(x) cos(3 pi/4) + sin(x) sin(3 pi/4) = 1/sqrt(2) * (-cos(x) + sin(x)) sin(X) = sin(x) cos(3 pi/4) - cos(x) sin(3 pi/4) = -1/sqrt(2) * (sin(x) + cos(x)) cf. Fdlibm. */ __sincosl (xx, &s, &c); ss = -s - c; cc = s - c; z = __cosl (xx + xx); if ((s * c) > 0) cc = z / ss; else ss = z / cc; z = ONEOSQPI * (p * ss + q * cc) / __ieee754_sqrtl (xx); return z; }
__complex__ long double __kernel_casinhl (__complex__ long double x, int adj) { __complex__ long double res; long double rx, ix; __complex__ long double y; /* Avoid cancellation by reducing to the first quadrant. */ rx = fabsl (__real__ x); ix = fabsl (__imag__ x); if (rx >= 1.0L / LDBL_EPSILON || ix >= 1.0L / LDBL_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) { long double t = __real__ y; __real__ y = __copysignl (__imag__ y, __imag__ x); __imag__ y = t; } res = __clogl (y); __real__ res += M_LN2l; } else if (rx >= 0.5L && ix < LDBL_EPSILON / 8.0L) { long double s = __ieee754_hypotl (1.0L, rx); __real__ res = __ieee754_logl (rx + s); if (adj) __imag__ res = __ieee754_atan2l (s, __imag__ x); else __imag__ res = __ieee754_atan2l (ix, s); } else if (rx < LDBL_EPSILON / 8.0L && ix >= 1.5L) { long double s = __ieee754_sqrtl ((ix + 1.0L) * (ix - 1.0L)); __real__ res = __ieee754_logl (ix + s); if (adj) __imag__ res = __ieee754_atan2l (rx, __copysignl (s, __imag__ x)); else __imag__ res = __ieee754_atan2l (s, rx); } else if (ix > 1.0L && ix < 1.5L && rx < 0.5L) { if (rx < LDBL_EPSILON * LDBL_EPSILON) { long double ix2m1 = (ix + 1.0L) * (ix - 1.0L); long double s = __ieee754_sqrtl (ix2m1); __real__ res = __log1pl (2.0L * (ix2m1 + ix * s)) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (rx, __copysignl (s, __imag__ x)); else __imag__ res = __ieee754_atan2l (s, rx); } else { long double ix2m1 = (ix + 1.0L) * (ix - 1.0L); long double rx2 = rx * rx; long double f = rx2 * (2.0L + rx2 + 2.0L * ix * ix); long double d = __ieee754_sqrtl (ix2m1 * ix2m1 + f); long double dp = d + ix2m1; long double dm = f / dp; long double r1 = __ieee754_sqrtl ((dm + rx2) / 2.0L); long double r2 = rx * ix / r1; __real__ res = __log1pl (rx2 + dp + 2.0L * (rx * r1 + ix * r2)) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (rx + r1, __copysignl (ix + r2, __imag__ x)); else __imag__ res = __ieee754_atan2l (ix + r2, rx + r1); } } else if (ix == 1.0L && rx < 0.5L) { if (rx < LDBL_EPSILON / 8.0L) { __real__ res = __log1pl (2.0L * (rx + __ieee754_sqrtl (rx))) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (__ieee754_sqrtl (rx), __copysignl (1.0L, __imag__ x)); else __imag__ res = __ieee754_atan2l (1.0L, __ieee754_sqrtl (rx)); } else { long double d = rx * __ieee754_sqrtl (4.0L + rx * rx); long double s1 = __ieee754_sqrtl ((d + rx * rx) / 2.0L); long double s2 = __ieee754_sqrtl ((d - rx * rx) / 2.0L); __real__ res = __log1pl (rx * rx + d + 2.0L * (rx * s1 + s2)) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (rx + s1, __copysignl (1.0L + s2, __imag__ x)); else __imag__ res = __ieee754_atan2l (1.0L + s2, rx + s1); } } else if (ix < 1.0L && rx < 0.5L) { if (ix >= LDBL_EPSILON) { if (rx < LDBL_EPSILON * LDBL_EPSILON) { long double onemix2 = (1.0L + ix) * (1.0L - ix); long double s = __ieee754_sqrtl (onemix2); __real__ res = __log1pl (2.0L * rx / s) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (s, __imag__ x); else __imag__ res = __ieee754_atan2l (ix, s); } else { long double onemix2 = (1.0L + ix) * (1.0L - ix); long double rx2 = rx * rx; long double f = rx2 * (2.0L + rx2 + 2.0L * ix * ix); long double d = __ieee754_sqrtl (onemix2 * onemix2 + f); long double dp = d + onemix2; long double dm = f / dp; long double r1 = __ieee754_sqrtl ((dp + rx2) / 2.0L); long double r2 = rx * ix / r1; __real__ res = __log1pl (rx2 + dm + 2.0L * (rx * r1 + ix * r2)) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (rx + r1, __copysignl (ix + r2, __imag__ x)); else __imag__ res = __ieee754_atan2l (ix + r2, rx + r1); } } else { long double s = __ieee754_hypotl (1.0L, rx); __real__ res = __log1pl (2.0L * rx * (rx + s)) / 2.0L; if (adj) __imag__ res = __ieee754_atan2l (s, __imag__ x); else __imag__ res = __ieee754_atan2l (ix, s); } if (__real__ res < LDBL_MIN) { volatile long double force_underflow = __real__ res * __real__ res; (void) force_underflow; } } else { __real__ y = (rx - ix) * (rx + ix) + 1.0L; __imag__ y = 2.0L * rx * ix; y = __csqrtl (y); __real__ y += rx; __imag__ y += ix; if (adj) { long double t = __real__ y; __real__ y = __copysignl (__imag__ y, __imag__ x); __imag__ y = t; } res = __clogl (y); } /* Give results the correct sign for the original argument. */ __real__ res = __copysignl (__real__ res, __real__ x); __imag__ res = __copysignl (__imag__ res, (adj ? 1.0L : __imag__ x)); return res; }
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); } }
_Float128 __ieee754_y0l(_Float128 x) { _Float128 xx, xinv, z, p, q, c, s, cc, ss; if (! isfinite (x)) { if (x != x) return x + x; else return 0; } if (x <= 0) { if (x < 0) return (zero / (zero * x)); return -HUGE_VALL + x; } xx = fabsl (x); if (xx <= 0x1p-57) return U0 + TWOOPI * __ieee754_logl (x); if (xx <= 2) { /* 0 <= x <= 2 */ z = xx * xx; p = neval (z, Y0_2N, NY0_2N) / deval (z, Y0_2D, NY0_2D); p = TWOOPI * __ieee754_logl (x) * __ieee754_j0l (x) + p; return p; } /* X = x - pi/4 cos(X) = cos(x) cos(pi/4) + sin(x) sin(pi/4) = 1/sqrt(2) * (cos(x) + sin(x)) sin(X) = sin(x) cos(pi/4) - cos(x) sin(pi/4) = 1/sqrt(2) * (sin(x) - cos(x)) sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) cf. Fdlibm. */ __sincosl (x, &s, &c); ss = s - c; cc = s + c; if (xx <= LDBL_MAX / 2) { z = -__cosl (x + x); if ((s * c) < 0) cc = z / ss; else ss = z / cc; } if (xx > L(0x1p256)) return ONEOSQPI * ss / __ieee754_sqrtl (x); xinv = 1 / xx; z = xinv * xinv; if (xinv <= 0.25) { if (xinv <= 0.125) { if (xinv <= 0.0625) { p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID); q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID); } else { p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D); q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D); } } else if (xinv <= 0.1875) { p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D); q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D); } else { p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D); q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D); } } /* .25 */ else /* if (xinv <= 0.5) */ { if (xinv <= 0.375) { if (xinv <= 0.3125) { p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D); q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D); } else { p = neval (z, P2r7_3r2N, NP2r7_3r2N) / deval (z, P2r7_3r2D, NP2r7_3r2D); q = neval (z, Q2r7_3r2N, NQ2r7_3r2N) / deval (z, Q2r7_3r2D, NQ2r7_3r2D); } } else if (xinv <= 0.4375) { p = neval (z, P2r3_2r7N, NP2r3_2r7N) / deval (z, P2r3_2r7D, NP2r3_2r7D); q = neval (z, Q2r3_2r7N, NQ2r3_2r7N) / deval (z, Q2r3_2r7D, NQ2r3_2r7D); } else { p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D); q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D); } } p = 1 + z * p; q = z * xinv * q; q = q - L(0.125) * xinv; z = ONEOSQPI * (p * ss + q * cc) / __ieee754_sqrtl (x); return z; }
long double __ieee754_hypotl(long double x, long double y) { long double a,b,t1,t2,y1,y2,w; u_int32_t j,k,ea,eb; GET_LDOUBLE_EXP(ea,x); ea &= 0x7fff; GET_LDOUBLE_EXP(eb,y); eb &= 0x7fff; if(eb > ea) {a=y;b=x;j=ea; ea=eb;eb=j;} else {a=x;b=y;} SET_LDOUBLE_EXP(a,ea); /* a <- |a| */ SET_LDOUBLE_EXP(b,eb); /* b <- |b| */ if((ea-eb)>0x46) {return a+b;} /* x/y > 2**70 */ k=0; if(__builtin_expect(ea > 0x5f3f,0)) { /* a>2**8000 */ if(ea == 0x7fff) { /* Inf or NaN */ u_int32_t exp __attribute__ ((unused)); u_int32_t high,low; w = a+b; /* for sNaN */ GET_LDOUBLE_WORDS(exp,high,low,a); if(((high&0x7fffffff)|low)==0) w = a; GET_LDOUBLE_WORDS(exp,high,low,b); if(((eb^0x7fff)|(high&0x7fffffff)|low)==0) w = b; return w; } /* scale a and b by 2**-9600 */ ea -= 0x2580; eb -= 0x2580; k += 9600; SET_LDOUBLE_EXP(a,ea); SET_LDOUBLE_EXP(b,eb); } if(__builtin_expect(eb < 0x20bf, 0)) { /* b < 2**-8000 */ if(eb == 0) { /* subnormal b or 0 */ u_int32_t exp __attribute__ ((unused)); u_int32_t high,low; GET_LDOUBLE_WORDS(exp,high,low,b); if((high|low)==0) return a; SET_LDOUBLE_WORDS(t1, 0x7ffd, 0x80000000, 0); /* t1=2^16382 */ b *= t1; a *= t1; k -= 16382; GET_LDOUBLE_EXP (ea, a); GET_LDOUBLE_EXP (eb, b); if (eb > ea) { t1 = a; a = b; b = t1; j = ea; ea = eb; eb = j; } } else { /* scale a and b by 2^9600 */ ea += 0x2580; /* a *= 2^9600 */ eb += 0x2580; /* b *= 2^9600 */ k -= 9600; SET_LDOUBLE_EXP(a,ea); SET_LDOUBLE_EXP(b,eb); } } /* medium size a and b */ w = a-b; if (w>b) { u_int32_t high; GET_LDOUBLE_MSW(high,a); SET_LDOUBLE_WORDS(t1,ea,high,0); t2 = a-t1; w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); } else { u_int32_t high; GET_LDOUBLE_MSW(high,b); a = a+a; SET_LDOUBLE_WORDS(y1,eb,high,0); y2 = b - y1; GET_LDOUBLE_MSW(high,a); SET_LDOUBLE_WORDS(t1,ea+1,high,0); t2 = a - t1; w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int32_t exp; t1 = 1.0; GET_LDOUBLE_EXP(exp,t1); SET_LDOUBLE_EXP(t1,exp+k); w *= t1; math_check_force_underflow_nonneg (w); return w; } else return w; }
long double __ieee754_j0l (long double x) { long double xx, xinv, z, p, q, c, s, cc, ss; if (! isfinite (x)) { if (x != x) return x; else return 0.0L; } if (x == 0.0L) return 1.0L; xx = fabsl (x); if (xx <= 2.0L) { /* 0 <= x <= 2 */ z = xx * xx; p = z * z * neval (z, J0_2N, NJ0_2N) / deval (z, J0_2D, NJ0_2D); p -= 0.25L * z; p += 1.0L; return p; } /* X = x - pi/4 cos(X) = cos(x) cos(pi/4) + sin(x) sin(pi/4) = 1/sqrt(2) * (cos(x) + sin(x)) sin(X) = sin(x) cos(pi/4) - cos(x) sin(pi/4) = 1/sqrt(2) * (sin(x) - cos(x)) sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) cf. Fdlibm. */ __sincosl (xx, &s, &c); ss = s - c; cc = s + c; if (xx <= LDBL_MAX / 2.0L) { z = -__cosl (xx + xx); if ((s * c) < 0) cc = z / ss; else ss = z / cc; } if (xx > 0x1p256L) return ONEOSQPI * cc / __ieee754_sqrtl (xx); xinv = 1.0L / xx; z = xinv * xinv; if (xinv <= 0.25) { if (xinv <= 0.125) { if (xinv <= 0.0625) { p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID); q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID); } else { p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D); q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D); } } else if (xinv <= 0.1875) { p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D); q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D); } else { p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D); q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D); } } /* .25 */ else /* if (xinv <= 0.5) */ { if (xinv <= 0.375) { if (xinv <= 0.3125) { p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D); q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D); } else { p = neval (z, P2r7_3r2N, NP2r7_3r2N) / deval (z, P2r7_3r2D, NP2r7_3r2D); q = neval (z, Q2r7_3r2N, NQ2r7_3r2N) / deval (z, Q2r7_3r2D, NQ2r7_3r2D); } } else if (xinv <= 0.4375) { p = neval (z, P2r3_2r7N, NP2r3_2r7N) / deval (z, P2r3_2r7D, NP2r3_2r7D); q = neval (z, Q2r3_2r7N, NQ2r3_2r7N) / deval (z, Q2r3_2r7D, NQ2r3_2r7D); } else { p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D); q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D); } } p = 1.0L + z * p; q = z * xinv * q; q = q - 0.125L * xinv; z = ONEOSQPI * (p * cc - q * ss) / __ieee754_sqrtl (xx); return z; }
__complex__ long double __csqrtl (__complex__ long double x) { __complex__ long double 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_VALL; __imag__ res = __imag__ x; } else if (rcls == FP_INFINITE) { if (__real__ x < 0.0) { __real__ res = icls == FP_NAN ? __nanl ("") : 0; __imag__ res = __copysignl (HUGE_VALL, __imag__ x); } else { __real__ res = __real__ x; __imag__ res = (icls == FP_NAN ? __nanl ("") : __copysignl (0.0, __imag__ x)); } } else { __real__ res = __nanl (""); __imag__ res = __nanl (""); } } else { if (__builtin_expect (icls == FP_ZERO, 0)) { if (__real__ x < 0.0) { __real__ res = 0.0; __imag__ res = __copysignl (__ieee754_sqrtl (-__real__ x), __imag__ x); } else { __real__ res = fabsl (__ieee754_sqrtl (__real__ x)); __imag__ res = __copysignl (0.0, __imag__ x); } } else if (__builtin_expect (rcls == FP_ZERO, 0)) { long double r = __ieee754_sqrtl (0.5 * fabsl (__imag__ x)); __real__ res = r; __imag__ res = __copysignl (r, __imag__ x); } else { long double d, r, s; d = __ieee754_hypotl (__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_sqrtl (0.5L * d + 0.5L * __real__ x); s = (0.5L * __imag__ x) / r; } else { s = __ieee754_sqrtl (0.5L * d - 0.5L * __real__ x); r = fabsl ((0.5L * __imag__ x) / s); } __real__ res = r; __imag__ res = __copysignl (s, __imag__ x); } } return res; }
long double __ieee754_hypotl(long double x, long double y) { long double a,b,t1,t2,y1,y2,w; int64_t j,k,ha,hb; GET_LDOUBLE_MSW64(ha,x); ha &= 0x7fffffffffffffffLL; GET_LDOUBLE_MSW64(hb,y); hb &= 0x7fffffffffffffffLL; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} SET_LDOUBLE_MSW64(a,ha); /* a <- |a| */ SET_LDOUBLE_MSW64(b,hb); /* b <- |b| */ if((ha-hb)>0x78000000000000LL) {return a+b;} /* x/y > 2**120 */ k=0; if(ha > 0x5f3f000000000000LL) { /* a>2**8000 */ if(ha >= 0x7fff000000000000LL) { /* Inf or NaN */ u_int64_t low; w = a+b; /* for sNaN */ GET_LDOUBLE_LSW64(low,a); if(((ha&0xffffffffffffLL)|low)==0) w = a; GET_LDOUBLE_LSW64(low,b); if(((hb^0x7fff000000000000LL)|low)==0) w = b; return w; } /* scale a and b by 2**-9600 */ ha -= 0x2580000000000000LL; hb -= 0x2580000000000000LL; k += 9600; SET_LDOUBLE_MSW64(a,ha); SET_LDOUBLE_MSW64(b,hb); } if(hb < 0x20bf000000000000LL) { /* b < 2**-8000 */ if(hb <= 0x0000ffffffffffffLL) { /* subnormal b or 0 */ u_int64_t low; GET_LDOUBLE_LSW64(low,b); if((hb|low)==0) return a; t1=0; SET_LDOUBLE_MSW64(t1,0x7ffd000000000000LL); /* t1=2^16382 */ b *= t1; a *= t1; k -= 16382; GET_LDOUBLE_MSW64 (ha, a); GET_LDOUBLE_MSW64 (hb, b); if (hb > ha) { t1 = a; a = b; b = t1; j = ha; ha = hb; hb = j; } } else { /* scale a and b by 2^9600 */ ha += 0x2580000000000000LL; /* a *= 2^9600 */ hb += 0x2580000000000000LL; /* b *= 2^9600 */ k -= 9600; SET_LDOUBLE_MSW64(a,ha); SET_LDOUBLE_MSW64(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { t1 = 0; SET_LDOUBLE_MSW64(t1,ha); t2 = a-t1; w = __ieee754_sqrtl(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; y1 = 0; SET_LDOUBLE_MSW64(y1,hb); y2 = b - y1; t1 = 0; SET_LDOUBLE_MSW64(t1,ha+0x0001000000000000LL); t2 = a - t1; w = __ieee754_sqrtl(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { u_int64_t high; t1 = 1.0L; GET_LDOUBLE_MSW64(high,t1); SET_LDOUBLE_MSW64(t1,high+(k<<48)); return t1*w; } else return w; }
long double __ieee754_j1l (long double x) { long double xx, xinv, z, p, q, c, s, cc, ss; if (! isfinite (x)) { if (x != x) return x; else return 0.0L; } if (x == 0.0L) return x; xx = fabsl (x); if (xx <= 0x1p-58L) { long double ret = x * 0.5L; if (fabsl (ret) < LDBL_MIN) { long double force_underflow = ret * ret; math_force_eval (force_underflow); } return ret; } if (xx <= 2.0L) { /* 0 <= x <= 2 */ z = xx * xx; p = xx * z * neval (z, J0_2N, NJ0_2N) / deval (z, J0_2D, NJ0_2D); p += 0.5L * xx; if (x < 0) p = -p; return p; } /* X = x - 3 pi/4 cos(X) = cos(x) cos(3 pi/4) + sin(x) sin(3 pi/4) = 1/sqrt(2) * (-cos(x) + sin(x)) sin(X) = sin(x) cos(3 pi/4) - cos(x) sin(3 pi/4) = -1/sqrt(2) * (sin(x) + cos(x)) cf. Fdlibm. */ __sincosl (xx, &s, &c); ss = -s - c; cc = s - c; if (xx <= LDBL_MAX / 2.0L) { z = __cosl (xx + xx); if ((s * c) > 0) cc = z / ss; else ss = z / cc; } if (xx > 0x1p256L) { z = ONEOSQPI * cc / __ieee754_sqrtl (xx); if (x < 0) z = -z; return z; } xinv = 1.0L / xx; z = xinv * xinv; if (xinv <= 0.25) { if (xinv <= 0.125) { if (xinv <= 0.0625) { p = neval (z, P16_IN, NP16_IN) / deval (z, P16_ID, NP16_ID); q = neval (z, Q16_IN, NQ16_IN) / deval (z, Q16_ID, NQ16_ID); } else { p = neval (z, P8_16N, NP8_16N) / deval (z, P8_16D, NP8_16D); q = neval (z, Q8_16N, NQ8_16N) / deval (z, Q8_16D, NQ8_16D); } } else if (xinv <= 0.1875) { p = neval (z, P5_8N, NP5_8N) / deval (z, P5_8D, NP5_8D); q = neval (z, Q5_8N, NQ5_8N) / deval (z, Q5_8D, NQ5_8D); } else { p = neval (z, P4_5N, NP4_5N) / deval (z, P4_5D, NP4_5D); q = neval (z, Q4_5N, NQ4_5N) / deval (z, Q4_5D, NQ4_5D); } } /* .25 */ else /* if (xinv <= 0.5) */ { if (xinv <= 0.375) { if (xinv <= 0.3125) { p = neval (z, P3r2_4N, NP3r2_4N) / deval (z, P3r2_4D, NP3r2_4D); q = neval (z, Q3r2_4N, NQ3r2_4N) / deval (z, Q3r2_4D, NQ3r2_4D); } else { p = neval (z, P2r7_3r2N, NP2r7_3r2N) / deval (z, P2r7_3r2D, NP2r7_3r2D); q = neval (z, Q2r7_3r2N, NQ2r7_3r2N) / deval (z, Q2r7_3r2D, NQ2r7_3r2D); } } else if (xinv <= 0.4375) { p = neval (z, P2r3_2r7N, NP2r3_2r7N) / deval (z, P2r3_2r7D, NP2r3_2r7D); q = neval (z, Q2r3_2r7N, NQ2r3_2r7N) / deval (z, Q2r3_2r7D, NQ2r3_2r7D); } else { p = neval (z, P2_2r3N, NP2_2r3N) / deval (z, P2_2r3D, NP2_2r3D); q = neval (z, Q2_2r3N, NQ2_2r3N) / deval (z, Q2_2r3D, NQ2_2r3D); } } p = 1.0L + z * p; q = z * q; q = q * xinv + 0.375L * xinv; z = ONEOSQPI * (p * cc - q * ss) / __ieee754_sqrtl (xx); if (x < 0) z = -z; return z; }