float __ieee754_atanhf (float x) { float xa = fabsf (x); float t; if (isless (xa, 0.5f)) { if (__glibc_unlikely (xa < 0x1.0p-28f)) { math_force_eval (huge + x); math_check_force_underflow (x); return x; } t = xa + xa; t = 0.5f * __log1pf (t + t * xa / (1.0f - xa)); } else if (__glibc_likely (isless (xa, 1.0f))) t = 0.5f * __log1pf ((xa + xa) / (1.0f - xa)); else { if (isgreater (xa, 1.0f)) return (x - x) / (x - x); return x / 0.0f; } return __copysignf (t, x); }
double __asinh (double x) { double w; int32_t hx, ix; GET_HIGH_WORD (hx, x); ix = hx & 0x7fffffff; if (__glibc_unlikely (ix < 0x3e300000)) /* |x|<2**-28 */ { math_check_force_underflow (x); if (huge + x > one) return x; /* return x inexact except 0 */ } if (__glibc_unlikely (ix > 0x41b00000)) /* |x| > 2**28 */ { if (ix >= 0x7ff00000) return x + x; /* x is inf or NaN */ w = __ieee754_log (fabs (x)) + ln2; } else { double xa = fabs (x); if (ix > 0x40000000) /* 2**28 > |x| > 2.0 */ { w = __ieee754_log (2.0 * xa + one / (sqrt (xa * xa + one) + xa)); } else /* 2.0 > |x| > 2**-28 */ { double t = xa * xa; w = __log1p (xa + t / (one + sqrt (one + t))); } } return copysign (w, x); }
float __asinhf(float x) { float w; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(__builtin_expect(ix< 0x38000000, 0)) { /* |x|<2**-14 */ math_check_force_underflow (x); if(huge+x>one) return x; /* return x inexact except 0 */ } if(__builtin_expect(ix>0x47000000, 0)) { /* |x| > 2**14 */ if(ix>=0x7f800000) return x+x; /* x is inf or NaN */ w = __ieee754_logf(fabsf(x))+ln2; } else { float xa = fabsf(x); if (ix>0x40000000) { /* 2**14 > |x| > 2.0 */ w = __ieee754_logf(2.0f*xa+one/(__ieee754_sqrtf(xa*xa+one)+xa)); } else { /* 2.0 > |x| > 2**-14 */ float t = xa*xa; w =__log1pf(xa+t/(one+__ieee754_sqrtf(one+t))); } } return __copysignf(w, x); }
double __ieee754_atanh (double x) { double xa = fabs (x); double t; if (isless (xa, 0.5)) { if (__glibc_unlikely (xa < 0x1.0p-28)) { math_force_eval (huge + x); math_check_force_underflow (x); return x; } t = xa + xa; t = 0.5 * __log1p (t + t * xa / (1.0 - xa)); } else if (__glibc_likely (isless (xa, 1.0))) t = 0.5 * __log1p ((xa + xa) / (1.0 - xa)); else { if (isgreater (xa, 1.0)) return (x - x) / (x - x); return x / 0.0; } return __copysign (t, x); }
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/(sqrtl(x*x+one)+t)); } else { /* 2.0 >= |x| >= 2**-56 */ t = x*x; w =__log1pl(fabsl(x)+t/(one+sqrtl(one+t))); } if(hx>0) return w; else return -w; }
__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 __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; }
float __atanf(float x) { float w,s1,s2,z; int32_t ix,hx,id; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x4c000000) { /* if |x| >= 2^25 */ if(ix>0x7f800000) return x+x; /* NaN */ if(hx>0) return atanhi[3]+atanlo[3]; else return -atanhi[3]-atanlo[3]; } if (ix < 0x3ee00000) { /* |x| < 0.4375 */ if (ix < 0x31000000) { /* |x| < 2^-29 */ math_check_force_underflow (x); if(huge+x>one) return x; /* raise inexact */ } id = -1; } else { x = fabsf(x); if (ix < 0x3f980000) { /* |x| < 1.1875 */ if (ix < 0x3f300000) { /* 7/16 <=|x|<11/16 */ id = 0; x = ((float)2.0*x-one)/((float)2.0+x); } else { /* 11/16<=|x|< 19/16 */ id = 1; x = (x-one)/(x+one); } } else { if (ix < 0x401c0000) { /* |x| < 2.4375 */ id = 2; x = (x-(float)1.5)/(one+(float)1.5*x); } else { /* 2.4375 <= |x| < 2^66 */ id = 3; x = -(float)1.0/x; } }} /* end of argument reduction */ z = x*x; w = z*z; /* break sum from i=0 to 10 aT[i]z**(i+1) into odd and even poly */ s1 = z*(aT[0]+w*(aT[2]+w*(aT[4]+w*(aT[6]+w*(aT[8]+w*aT[10]))))); s2 = w*(aT[1]+w*(aT[3]+w*(aT[5]+w*(aT[7]+w*aT[9])))); if (id<0) return x - x*(s1+s2); else { z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x); return (hx<0)? -z:z; } }
long double __kernel_sinl(long double x, long double y, int iy) { long double absx, h, l, z, sin_l, cos_l_m1; int index; absx = fabsl (x); if (absx < 0.1484375L) { /* Argument is small enough to approximate it by a Chebyshev polynomial of degree 17. */ if (absx < 0x1p-33L) { math_check_force_underflow (x); if (!((int)x)) return x; /* generate inexact */ } z = x * x; return x + (x * (z*(SIN1+z*(SIN2+z*(SIN3+z*(SIN4+ z*(SIN5+z*(SIN6+z*(SIN7+z*SIN8))))))))); } else { /* So that we don't have to use too large polynomial, we find l and h such that x = l + h, where fabsl(l) <= 1.0/256 with 83 possible values for h. We look up cosl(h) and sinl(h) in pre-computed tables, compute cosl(l) and sinl(l) using a Chebyshev polynomial of degree 10(11) and compute sinl(h+l) = sinl(h)cosl(l) + cosl(h)sinl(l). */ index = (int) (128 * (absx - (0.1484375L - 1.0L / 256.0L))); h = 0.1484375L + index / 128.0; index *= 4; if (iy) l = (x < 0 ? -y : y) - (h - absx); else l = absx - h; z = l * l; sin_l = l*(ONE+z*(SSIN1+z*(SSIN2+z*(SSIN3+z*(SSIN4+z*SSIN5))))); cos_l_m1 = z*(SCOS1+z*(SCOS2+z*(SCOS3+z*(SCOS4+z*SCOS5)))); z = __sincosl_table [index + SINCOSL_SIN_HI] + (__sincosl_table [index + SINCOSL_SIN_LO] + (__sincosl_table [index + SINCOSL_SIN_HI] * cos_l_m1) + (__sincosl_table [index + SINCOSL_COS_HI] * sin_l)); return (x < 0) ? -z : z; } }
float __kernel_sinf(float x, float y, int iy) { float z,r,v; int32_t ix; GET_FLOAT_WORD(ix,x); ix &= 0x7fffffff; /* high word of x */ if(ix<0x32000000) /* |x| < 2**-27 */ { math_check_force_underflow (x); if ((int) x == 0) return x; /* generate inexact */ } z = x*x; v = z*x; r = S2+z*(S3+z*(S4+z*(S5+z*S6))); if(iy==0) return x+v*(S1+z*r); else return x-((z*(half*y-v*r)-y)-v*S1); }
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_sinhl(long double x) { long double t,w,h; uint32_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 */ math_check_force_underflow (x); 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 __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; }
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); }
float __tanhf(float x) { float t,z; int32_t jx,ix; GET_FLOAT_WORD(jx,x); ix = jx&0x7fffffff; /* x is INF or NaN */ if(ix>=0x7f800000) { if (jx>=0) return one/x+one; /* tanh(+-inf)=+-1 */ else return one/x-one; /* tanh(NaN) = NaN */ } /* |x| < 22 */ if (ix < 0x41b00000) { /* |x|<22 */ if (ix == 0) return x; /* x == +-0 */ if (ix<0x24000000) /* |x|<2**-55 */ { math_check_force_underflow (x); return x*(one+x); /* tanh(small) = small */ } if (ix>=0x3f800000) { /* |x|>=1 */ t = __expm1f(two*fabsf(x)); z = one - two/(t+two); } else { t = __expm1f(-two*fabsf(x)); z= -t/(t+two); } /* |x| > 22, return +-1 */ } else { z = one - tiny; /* raised inexact flag */ } return (jx>=0)? z: -z; }
long double __expm1l (long double x) { long double px, qx, xx; int32_t ix, sign; ieee854_long_double_shape_type u; int k; /* Detect infinity and NaN. */ u.value = x; ix = u.parts32.w0; sign = ix & 0x80000000; ix &= 0x7fffffff; if (!sign && ix >= 0x40060000) { /* If num is positive and exp >= 6 use plain exp. */ return __expl (x); } if (ix >= 0x7fff0000) { /* Infinity (which must be negative infinity). */ if (((ix & 0xffff) | u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0) return -1.0L; /* NaN. No invalid exception. */ return x; } /* expm1(+- 0) = +- 0. */ if ((ix == 0) && (u.parts32.w1 | u.parts32.w2 | u.parts32.w3) == 0) return x; /* Minimum value. */ if (x < minarg) return (4.0/big - 1.0L); /* Avoid internal underflow when result does not underflow, while ensuring underflow (without returning a zero of the wrong sign) when the result does underflow. */ if (fabsl (x) < 0x1p-113L) { math_check_force_underflow (x); return x; } /* Express x = ln 2 (k + remainder), remainder not exceeding 1/2. */ xx = C1 + C2; /* ln 2. */ px = __floorl (0.5 + x / xx); k = px; /* remainder times ln 2 */ x -= px * C1; x -= px * C2; /* Approximate exp(remainder ln 2). */ px = (((((((P7 * x + P6) * x + P5) * x + P4) * x + P3) * x + P2) * x + P1) * x + P0) * x; qx = (((((((x + Q7) * x + Q6) * x + Q5) * x + Q4) * x + Q3) * x + Q2) * x + Q1) * x + Q0; xx = x * x; qx = x + (0.5 * xx + xx * px / qx); /* exp(x) = exp(k ln 2) exp(remainder ln 2) = 2^k exp(remainder ln 2). We have qx = exp(remainder ln 2) - 1, so exp(x) - 1 = 2^k (qx + 1) - 1 = 2^k qx + 2^k - 1. */ px = __ldexpl (1.0L, k); x = px * qx + (px - 1.0); return x; }
double __ieee754_j1 (double x) { double z, s, c, ss, cc, r, u, v, y, r1, r2, s1, s2, s3, z2, z4; int32_t hx, ix; GET_HIGH_WORD (hx, x); ix = hx & 0x7fffffff; if (__glibc_unlikely (ix >= 0x7ff00000)) return one / x; y = fabs (x); if (ix >= 0x40000000) /* |x| >= 2.0 */ { __sincos (y, &s, &c); ss = -s - c; cc = s - c; if (ix < 0x7fe00000) /* make sure y+y not overflow */ { z = __cos (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) / sqrt (y); else { u = pone (y); v = qone (y); z = invsqrtpi * (u * cc - v * ss) / sqrt (y); } if (hx < 0) return -z; else return z; } if (__glibc_unlikely (ix < 0x3e400000)) /* |x|<2**-27 */ { if (huge + x > one) /* inexact if x!=0 necessary */ { double ret = math_narrow_eval (0.5 * x); math_check_force_underflow (ret); if (ret == 0 && x != 0) __set_errno (ERANGE); return ret; } } z = x * x; r1 = z * R[0]; z2 = z * z; r2 = R[1] + z * R[2]; z4 = z2 * z2; r = r1 + z2 * r2 + z4 * R[3]; r *= x; s1 = one + z * S[1]; s2 = S[2] + z * S[3]; s3 = S[4] + z * S[5]; s = s1 + z2 * s2 + z4 * s3; return (x * 0.5 + r / s); }
long double __atanl (long double x) { int32_t k, sign, lx; long double t, u, p, q; double xhi; xhi = ldbl_high (x); EXTRACT_WORDS (k, lx, xhi); sign = k & 0x80000000; /* Check for IEEE special cases. */ k &= 0x7fffffff; if (k >= 0x7ff00000) { /* NaN. */ if (((k - 0x7ff00000) | lx) != 0) return (x + x); /* Infinity. */ if (sign) return -atantbl[83]; else return atantbl[83]; } if (k <= 0x3c800000) /* |x| <= 2**-55. */ { math_check_force_underflow (x); /* Raise inexact. */ if (1e300L + x > 0.0) return x; } if (k >= 0x46c00000) /* |x| >= 2**109. */ { /* Saturate result to {-,+}pi/2. */ if (sign) return -atantbl[83]; else return atantbl[83]; } if (sign) x = -x; if (k >= 0x40248000) /* 10.25 */ { k = 83; t = -1.0/x; } else { /* Index of nearest table element. Roundoff to integer is asymmetrical to avoid cancellation when t < 0 (cf. fdlibm). */ k = 8.0 * x + 0.25; u = 0.125 * k; /* Small arctan argument. */ t = (x - u) / (1.0 + x * u); } /* Arctan of small argument t. */ u = t * t; p = ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0; q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0; u = t * u * p / q + t; /* arctan x = arctan u + arctan t */ u = atantbl[k] + u; if (sign) return (-u); else return u; }
double SECTION __sin (double x) { double xx, res, t, cor, y, s, c, sn, ssn, cs, ccs, xn, a, da, db, eps, xn1, xn2; mynumber u, v; int4 k, m, n; double retval = 0; SET_RESTORE_ROUND_53BIT (FE_TONEAREST); u.x = x; m = u.i[HIGH_HALF]; k = 0x7fffffff & m; /* no sign */ if (k < 0x3e500000) /* if x->0 =>sin(x)=x */ { math_check_force_underflow (x); retval = x; } /*---------------------------- 2^-26 < |x|< 0.25 ----------------------*/ else if (k < 0x3fd00000) { xx = x * x; /* Taylor series. */ t = POLYNOMIAL (xx) * (xx * x); res = x + t; cor = (x - res) + t; retval = (res == res + 1.07 * cor) ? res : slow (x); } /* else if (k < 0x3fd00000) */ /*---------------------------- 0.25<|x|< 0.855469---------------------- */ else if (k < 0x3feb6000) { u.x = (m > 0) ? big + x : big - x; y = (m > 0) ? x - (u.x - big) : x + (u.x - big); xx = y * y; s = y + y * xx * (sn3 + xx * sn5); c = xx * (cs2 + xx * (cs4 + xx * cs6)); SINCOS_TABLE_LOOKUP (u, sn, ssn, cs, ccs); if (m <= 0) { sn = -sn; ssn = -ssn; } cor = (ssn + s * ccs - sn * c) + cs * s; res = sn + cor; cor = (sn - res) + cor; retval = (res == res + 1.096 * cor) ? res : slow1 (x); } /* else if (k < 0x3feb6000) */ /*----------------------- 0.855469 <|x|<2.426265 ----------------------*/ else if (k < 0x400368fd) { y = (m > 0) ? hp0 - x : hp0 + x; if (y >= 0) { u.x = big + y; y = (y - (u.x - big)) + hp1; } else { u.x = big - y; y = (-hp1) - (y + (u.x - big)); } res = do_cos (u, y, &cor); retval = (res == res + 1.020 * cor) ? ((m > 0) ? res : -res) : slow2 (x); } /* else if (k < 0x400368fd) */ /*-------------------------- 2.426265<|x|< 105414350 ----------------------*/ else if (k < 0x419921FB) { t = (x * hpinv + toint); xn = t - toint; v.x = t; y = (x - xn * mp1) - xn * mp2; n = v.i[LOW_HALF] & 3; da = xn * mp3; a = y - da; da = (y - a) - da; eps = fabs (x) * 1.2e-30; switch (n) { /* quarter of unit circle */ case 0: case 2: xx = a * a; if (n) { a = -a; da = -da; } if (xx < 0.01588) { /* Taylor series. */ res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps; retval = (res == res + cor) ? res : sloww (a, da, x); } else { if (a > 0) m = 1; else { m = 0; a = -a; da = -da; } u.x = big + a; y = a - (u.x - big); res = do_sin (u, y, da, &cor); cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps; retval = ((res == res + cor) ? ((m) ? res : -res) : sloww1 (a, da, x, m)); } break; case 1: case 3: if (a < 0) { a = -a; da = -da; } u.x = big + a; y = a - (u.x - big) + da; res = do_cos (u, y, &cor); cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps; retval = ((res == res + cor) ? ((n & 2) ? -res : res) : sloww2 (a, da, x, n)); break; } } /* else if (k < 0x419921FB ) */ /*---------------------105414350 <|x|< 281474976710656 --------------------*/ else if (k < 0x42F00000) { t = (x * hpinv + toint); xn = t - toint; v.x = t; xn1 = (xn + 8.0e22) - 8.0e22; xn2 = xn - xn1; y = ((((x - xn1 * mp1) - xn1 * mp2) - xn2 * mp1) - xn2 * mp2); n = v.i[LOW_HALF] & 3; da = xn1 * pp3; t = y - da; da = (y - t) - da; da = (da - xn2 * pp3) - xn * pp4; a = t + da; da = (t - a) + da; eps = 1.0e-24; switch (n) { case 0: case 2: xx = a * a; if (n) { a = -a; da = -da; } if (xx < 0.01588) { /* Taylor series. */ res = TAYLOR_SIN (xx, a, da, cor); cor = (cor > 0) ? 1.02 * cor + eps : 1.02 * cor - eps; retval = (res == res + cor) ? res : bsloww (a, da, x, n); } else { double t; if (a > 0) { m = 1; t = a; db = da; } else { m = 0; t = -a; db = -da; } u.x = big + t; y = t - (u.x - big); res = do_sin (u, y, db, &cor); cor = (cor > 0) ? 1.035 * cor + eps : 1.035 * cor - eps; retval = ((res == res + cor) ? ((m) ? res : -res) : bsloww1 (a, da, x, n)); } break; case 1: case 3: if (a < 0) { a = -a; da = -da; } u.x = big + a; y = a - (u.x - big) + da; res = do_cos (u, y, &cor); cor = (cor > 0) ? 1.025 * cor + eps : 1.025 * cor - eps; retval = ((res == res + cor) ? ((n & 2) ? -res : res) : bsloww2 (a, da, x, n)); break; } } /* else if (k < 0x42F00000 ) */ /* -----------------281474976710656 <|x| <2^1024----------------------------*/ else if (k < 0x7ff00000) retval = reduce_and_compute (x, 0); /*--------------------- |x| > 2^1024 ----------------------------------*/ else { if (k == 0x7ff00000 && u.i[LOW_HALF] == 0) __set_errno (EDOM); retval = x / x; } return retval; }
_Float128 __atanl (_Float128 x) { int k, sign; _Float128 t, u, p, q; ieee854_long_double_shape_type s; s.value = x; k = s.parts32.w0; if (k & 0x80000000) sign = 1; else sign = 0; /* Check for IEEE special cases. */ k &= 0x7fffffff; if (k >= 0x7fff0000) { /* NaN. */ if ((k & 0xffff) | s.parts32.w1 | s.parts32.w2 | s.parts32.w3) return (x + x); /* Infinity. */ if (sign) return -atantbl[83]; else return atantbl[83]; } if (k <= 0x3fc50000) /* |x| < 2**-58 */ { math_check_force_underflow (x); /* Raise inexact. */ if (huge + x > 0.0) return x; } if (k >= 0x40720000) /* |x| > 2**115 */ { /* Saturate result to {-,+}pi/2 */ if (sign) return -atantbl[83]; else return atantbl[83]; } if (sign) x = -x; if (k >= 0x40024800) /* 10.25 */ { k = 83; t = -1.0/x; } else { /* Index of nearest table element. Roundoff to integer is asymmetrical to avoid cancellation when t < 0 (cf. fdlibm). */ k = 8.0 * x + 0.25; u = L(0.125) * k; /* Small arctan argument. */ t = (x - u) / (1.0 + x * u); } /* Arctan of small argument t. */ u = t * t; p = ((((p4 * u) + p3) * u + p2) * u + p1) * u + p0; q = ((((u + q4) * u + q3) * u + q2) * u + q1) * u + q0; u = t * u * p / q + t; /* arctan x = arctan u + arctan t */ u = atantbl[k] + u; if (sign) return (-u); else return u; }
CFLOAT M_DECL_FUNC (__csqrt) (CFLOAT x) { CFLOAT res; int rcls = fpclassify (__real__ x); int icls = fpclassify (__imag__ x); if (__glibc_unlikely (rcls <= FP_INFINITE || icls <= FP_INFINITE)) { if (icls == FP_INFINITE) { __real__ res = M_HUGE_VAL; __imag__ res = __imag__ x; } else if (rcls == FP_INFINITE) { if (__real__ x < 0) { __real__ res = icls == FP_NAN ? M_NAN : 0; __imag__ res = M_COPYSIGN (M_HUGE_VAL, __imag__ x); } else { __real__ res = __real__ x; __imag__ res = (icls == FP_NAN ? M_NAN : M_COPYSIGN (0, __imag__ x)); } } else { __real__ res = M_NAN; __imag__ res = M_NAN; } } else { if (__glibc_unlikely (icls == FP_ZERO)) { if (__real__ x < 0) { __real__ res = 0; __imag__ res = M_COPYSIGN (M_SQRT (-__real__ x), __imag__ x); } else { __real__ res = M_FABS (M_SQRT (__real__ x)); __imag__ res = M_COPYSIGN (0, __imag__ x); } } else if (__glibc_unlikely (rcls == FP_ZERO)) { FLOAT r; if (M_FABS (__imag__ x) >= 2 * M_MIN) r = M_SQRT (M_LIT (0.5) * M_FABS (__imag__ x)); else r = M_LIT (0.5) * M_SQRT (2 * M_FABS (__imag__ x)); __real__ res = r; __imag__ res = M_COPYSIGN (r, __imag__ x); } else { FLOAT d, r, s; int scale = 0; if (M_FABS (__real__ x) > M_MAX / 4) { scale = 1; __real__ x = M_SCALBN (__real__ x, -2 * scale); __imag__ x = M_SCALBN (__imag__ x, -2 * scale); } else if (M_FABS (__imag__ x) > M_MAX / 4) { scale = 1; if (M_FABS (__real__ x) >= 4 * M_MIN) __real__ x = M_SCALBN (__real__ x, -2 * scale); else __real__ x = 0; __imag__ x = M_SCALBN (__imag__ x, -2 * scale); } else if (M_FABS (__real__ x) < 2 * M_MIN && M_FABS (__imag__ x) < 2 * M_MIN) { scale = -((M_MANT_DIG + 1) / 2); __real__ x = M_SCALBN (__real__ x, -2 * scale); __imag__ x = M_SCALBN (__imag__ x, -2 * scale); } d = M_HYPOT (__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 = M_SQRT (M_LIT (0.5) * (d + __real__ x)); if (scale == 1 && M_FABS (__imag__ x) < 1) { /* Avoid possible intermediate underflow. */ s = __imag__ x / r; r = M_SCALBN (r, scale); scale = 0; } else s = M_LIT (0.5) * (__imag__ x / r); } else { s = M_SQRT (M_LIT (0.5) * (d - __real__ x)); if (scale == 1 && M_FABS (__imag__ x) < 1) { /* Avoid possible intermediate underflow. */ r = M_FABS (__imag__ x / s); s = M_SCALBN (s, scale); scale = 0; } else r = M_FABS (M_LIT (0.5) * (__imag__ x / s)); } if (scale) { r = M_SCALBN (r, scale); s = M_SCALBN (s, scale); } math_check_force_underflow (r); math_check_force_underflow (s); __real__ res = r; __imag__ res = M_COPYSIGN (s, __imag__ x); } } return res; }
long double __kernel_tanl (long double x, long double y, int iy) { long double z, r, v, w, s; int32_t ix, sign, hx, lx; double xhi; xhi = ldbl_high (x); EXTRACT_WORDS (hx, lx, xhi); ix = hx & 0x7fffffff; if (ix < 0x3c600000) /* x < 2**-57 */ { if ((int) x == 0) /* generate inexact */ { if ((ix | lx | (iy + 1)) == 0) return one / fabs (x); else if (iy == 1) { math_check_force_underflow (x); return x; } else return -one / x; } } if (ix >= 0x3fe59420) /* |x| >= 0.6743316650390625 */ { if ((hx & 0x80000000) != 0) { x = -x; y = -y; sign = -1; } else sign = 1; z = pio4hi - x; w = pio4lo - y; x = z + w; y = 0.0; } z = x * x; r = T0 + z * (T1 + z * (T2 + z * (T3 + z * T4))); v = U0 + z * (U1 + z * (U2 + z * (U3 + z * (U4 + z)))); r = r / v; s = z * x; r = y + z * (s * r + y); r += TH * s; w = x + r; if (ix >= 0x3fe59420) { v = (long double) iy; w = (v - 2.0 * (x - (w * w / (w + v) - r))); /* SIGN is set for arguments that reach this code, but not otherwise, resulting in warnings that it may be used uninitialized although in the cases where it is used it has always been set. */ DIAG_PUSH_NEEDS_COMMENT; DIAG_IGNORE_NEEDS_COMMENT (5, "-Wmaybe-uninitialized"); if (sign < 0) w = -w; DIAG_POP_NEEDS_COMMENT; return w; } if (iy == 1) return w; else { /* if allow error up to 2 ulp, simply return -1.0/(x+r) here */ /* compute -1.0/(x+r) accurately */ long double u1, z1; u1 = ldbl_high (w); v = r - (u1 - x); /* u1+v = r+x */ z = -1.0 / w; z1 = ldbl_high (z); s = 1.0 + z1 * u1; return z1 + z * (s + z1 * v); } }