double __ieee754_acosh(double x) { double t; int32_t hx; uint32_t lx; EXTRACT_WORDS(hx, lx, x); if (hx<0x3ff00000) { /* x < 1 */ return (x - x) / (x - x); } else if (hx >= 0x41b00000) { /* x > 2**28 */ if (hx >= 0x7ff00000) { /* x is inf of NaN */ return x + x; } else return __ieee754_log(x) + ln2; /* acosh(huge)=log(2x) */ } else if (((hx - 0x3ff00000) | lx) == 0) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ t = x*x; return __ieee754_log(2.0*x - one / (x + sqrt(t - one))); } else { /* 1<x<2 */ t = x - one; return log1p(t + sqrt(2.0*t + t*t)); } }
double __ieee754_acosh (double x) { int64_t hx; EXTRACT_WORDS64 (hx, x); if (hx > INT64_C (0x4000000000000000)) { if (__builtin_expect (hx >= INT64_C (0x41b0000000000000), 0)) { /* x > 2**28 */ if (hx >= INT64_C (0x7ff0000000000000)) /* x is inf of NaN */ return x + x; else return __ieee754_log (x) + ln2;/* acosh(huge)=log(2x) */ } /* 2**28 > x > 2 */ double t = x * x; return __ieee754_log (2.0 * x - one / (x + __ieee754_sqrt (t - one))); } else if (__builtin_expect (hx > INT64_C (0x3ff0000000000000), 1)) { /* 1<x<2 */ double t = x - one; return __log1p (t + __ieee754_sqrt (2.0 * t + t * t)); } else if (__builtin_expect (hx == INT64_C (0x3ff0000000000000), 1)) return 0.0; /* acosh(1) = 0 */ else /* x < 1 */ return (x - x) / (x - 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 */ { 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 / (__ieee754_sqrt (xa * xa + one) + xa)); } else /* 2.0 > |x| > 2**-28 */ { double t = xa * xa; w = __log1p (xa + t / (one + __ieee754_sqrt (one + t))); } } return __copysign (w, x); }
double __ieee754_y0(double x) { double z, s,c,ss,cc,u,v; int32_t hx,ix,lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0 */ if(ix>=0x7ff00000) return one/(x+x*x); if((ix|lx)==0) return -one/zero; if(hx<0) return zero/zero; if(ix >= 0x40000000) { /* |x| >= 2.0 */ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) * where x0 = x-pi/4 * Better formula: * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) * = 1/sqrt(2) * (sin(x) + cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ s = sin(x); c = cos(x); ss = s-c; cc = s+c; /* * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) */ if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = -cos(x+x); if ((s*c)<zero) cc = z/ss; else ss = z/cc; } if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x); else { u = pzero(x); v = qzero(x); z = invsqrtpi*(u*ss+v*cc)/sqrt(x); } return z; } if(ix<=0x3e400000) { /* x < 2**-27 */ return(u00 + tpi*__ieee754_log(x)); } z = x*x; u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); v = one+z*(v01+z*(v02+z*(v03+z*v04))); return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); }
double log(double x) /* wrapper log */ { #ifdef CYGSEM_LIBM_COMPAT_IEEE_ONLY return __ieee754_log(x); #else double z; z = __ieee754_log(x); if(cyg_libm_get_compat_mode() == CYGNUM_LIBM_COMPAT_IEEE || isnan(x) || x > 0.0) return z; if(x==0.0) return __kernel_standard(x,x,16); /* log(0) */ else return __kernel_standard(x,x,17); /* log(x<0) */ #endif }
double log(double x) /* wrapper log */ { #ifdef _IEEE_LIBM return __ieee754_log(x); #else double z; z = __ieee754_log(x); if(_LIB_VERSION == _IEEE_ || isnan(x) || x > 0.0) return z; if(x==0.0) return __kernel_standard(x,x,16); /* log(0) */ else return __kernel_standard(x,x,17); /* log(x<0) */ #endif }
double __ieee754_log10 (double x) { double y, z; int64_t i, hx; int32_t k; EXTRACT_WORDS64 (hx, x); k = 0; if (hx < INT64_C(0x0010000000000000)) { /* x < 2**-1022 */ if (__builtin_expect ((hx & UINT64_C(0x7fffffffffffffff)) == 0, 0)) return -two54 / (x - x); /* log(+-0)=-inf */ if (__builtin_expect (hx < 0, 0)) return (x - x) / (x - x); /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ EXTRACT_WORDS64 (hx, x); } /* scale up resulted in a NaN number */ if (__builtin_expect (hx >= UINT64_C(0x7ff0000000000000), 0)) return x + x; k += (hx >> 52) - 1023; i = ((uint64_t) k & UINT64_C(0x8000000000000000)) >> 63; hx = (hx & UINT64_C(0x000fffffffffffff)) | ((0x3ff - i) << 52); y = (double) (k + i); INSERT_WORDS64 (x, hx); z = y * log10_2lo + ivln10 * __ieee754_log (x); return z + y * log10_2hi; }
double __ieee754_log10(double x) { double y,z; int i,k,hx; unsigned lx; hx = CYG_LIBM_HI(x); /* high word of x */ lx = CYG_LIBM_LO(x); /* low word of x */ k=0; if (hx < 0x00100000) { /* x < 2**-1022 */ if (((hx&0x7fffffff)|lx)==0) return -two54/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ hx = CYG_LIBM_HI(x); /* high word of x */ } if (hx >= 0x7ff00000) return x+x; k += (hx>>20)-1023; i = ((unsigned)k&0x80000000)>>31; hx = (hx&0x000fffff)|((0x3ff-i)<<20); y = (double)(k+i); CYG_LIBM_HI(x) = hx; z = y*log10_2lo + ivln10*__ieee754_log(x); return z+y*log10_2hi; }
double __ieee754_log10(double x) { double y,z; int32_t i,k,hx; u_int32_t lx; EXTRACT_WORDS(hx,lx,x); k=0; if (hx < 0x00100000) { /* x < 2**-1022 */ if (((hx&0x7fffffff)|lx)==0) return -two54/zero; /* log(+-0)=-inf */ if (hx<0) return (x-x)/zero; /* log(-#) = NaN */ k -= 54; x *= two54; /* subnormal number, scale up x */ GET_HIGH_WORD(hx,x); } if (hx >= 0x7ff00000) return x+x; k += (hx>>20)-1023; i = ((u_int32_t)k&0x80000000)>>31; hx = (hx&0x000fffff)|((0x3ff-i)<<20); y = (double)(k+i); SET_HIGH_WORD(x,hx); z = y*log10_2lo + ivln10*__ieee754_log(x); return z+y*log10_2hi; }
double __ieee754_y1(double x) { double z, s,c,ss,cc,u,v,u1,u2,v1,v2,v3,z2,z4; int32_t hx,ix,lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ if(__builtin_expect(ix>=0x7ff00000, 0)) return one/(x+x*x); if(__builtin_expect((ix|lx)==0, 0)) return -HUGE_VAL+x; /* -inf and overflow exception. */; if(__builtin_expect(hx<0, 0)) return zero/(zero*x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ __sincos (x, &s, &c); ss = -s-c; cc = s-c; if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = __cos(x+x); if ((s*c)>zero) cc = z/ss; else ss = z/cc; } /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) * where x0 = x-3pi/4 * Better formula: * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = -1/sqrt(2) * (cos(x) + sin(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrt(x); else { u = pone(x); v = qone(x); z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrt(x); } return z; } if(__builtin_expect(ix<=0x3c900000, 0)) { /* x < 2**-54 */ return(-tpi/x); } z = x*x; #ifdef DO_NOT_USE_THIS u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); #else u1 = U0[0]+z*U0[1];z2=z*z; u2 = U0[2]+z*U0[3];z4=z2*z2; u = u1 + z2*u2 + z4*U0[4]; v1 = one+z*V0[0]; v2 = V0[1]+z*V0[2]; v3 = V0[3]+z*V0[4]; v = v1 + z2*v2 + z4*v3; #endif return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); }
void Math_log(void *fp) { F_Math_log *f; f = fp; *f->ret = __ieee754_log(f->x); }
//------------------------------------------------------------------------------ double Cmath::__ieee754_acosh( double x ) { static const double one = 1.0; static const double ln2 = 6.93147180559945286227e-01; // 0x3FE62E42, 0xFEFA39EF double t; Cmp_signed__int32 hx; Cmp_unsigned__int32 lx; extract_words( hx, lx, x ); if( hx < 0x3ff00000 ) { // x < 1 return ( x - x ) / ( x - x ); } else if( hx >= 0x41b00000 ) { // x > 2**28 if( hx >= 0x7ff00000 ) { // x is inf of NaN return x + x; } else { return __ieee754_log( x ) + ln2; // acosh(huge)=log(2x) } } else if( ( ( hx - 0x3ff00000 ) | lx ) == 0 ) { return 0.0; // acosh(1) = 0 } else if( hx > 0x40000000 ) { // 2**28 > x > 2 t = x * x; return __ieee754_log( 2.0 * x - one / ( x + __ieee754_sqrt( t - one ) ) ); } else { // 1<x<2 t = x - one; return log1p( t + __ieee754_sqrt( 2.0 * t + t * t ) ); } }
double __ieee754_y1(double x) { double z, s,c,ss,cc,u,v; int32_t hx,ix,lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* * y1(NaN) = NaN. * y1(Inf) = 0. * y1(-Inf) = NaN and raise invalid exception. */ if(ix>=0x7ff00000) return vone/(x+x*x); /* y1(+-0) = -inf and raise divide-by-zero exception. */ if((ix|lx)==0) return -one/vzero; /* y1(x<0) = NaN and raise invalid exception. */ if(hx<0) return vzero/vzero; if(ix >= 0x40000000) { /* |x| >= 2.0 */ s = sin(x); c = cos(x); ss = -s-c; cc = s-c; if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = cos(x+x); if ((s*c)>zero) cc = z/ss; else ss = z/cc; } /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) * where x0 = x-3pi/4 * Better formula: * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = -1/sqrt(2) * (cos(x) + sin(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ if(ix>0x48000000) z = (invsqrtpi*ss)/sqrt(x); else { u = pone(x); v = qone(x); z = invsqrtpi*(u*ss+v*cc)/sqrt(x); } return z; } if(ix<=0x3c900000) { /* x < 2**-54 */ return(-tpi/x); } z = x*x; u = U0[0]+z*(U0[1]+z*(U0[2]+z*(U0[3]+z*U0[4]))); v = one+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4])))); return(x*(u/v) + tpi*(__ieee754_j1(x)*__ieee754_log(x)-one/x)); }
double asinh(double x) { double t,w; int hx,ix; hx = CYG_LIBM_HI(x); ix = hx&0x7fffffff; if(ix>=0x7ff00000) return x+x; /* x is inf or NaN */ if(ix< 0x3e300000) { /* |x|<2**-28 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x41b00000) { /* |x| > 2**28 */ w = __ieee754_log(fabs(x))+ln2; } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ t = fabs(x); w = __ieee754_log(2.0*t+one/(sqrt(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; w =log1p(fabs(x)+t/(one+sqrt(one+t))); } if(hx>0) return w; else return -w; }
__complex__ double __clog (__complex__ double x) { __complex__ double result; int rcls = fpclassify (__real__ x); int icls = fpclassify (__imag__ x); if (__builtin_expect (rcls == FP_ZERO && icls == FP_ZERO, 0)) { /* Real and imaginary part are 0.0. */ __imag__ result = signbit (__real__ x) ? M_PI : 0.0; __imag__ result = __copysign (__imag__ result, __imag__ x); /* Yes, the following line raises an exception. */ __real__ result = -1.0 / fabs (__real__ x); } else if (__builtin_expect (rcls != FP_NAN && icls != FP_NAN, 1)) { /* Neither real nor imaginary part is NaN. */ double d; int scale = 0; if (fabs (__real__ x) > DBL_MAX / 2.0 || fabs (__imag__ x) > DBL_MAX / 2.0) { scale = -1; __real__ x = __scalbn (__real__ x, scale); __imag__ x = __scalbn (__imag__ x, scale); } else if (fabs (__real__ x) < DBL_MIN && fabs (__imag__ x) < DBL_MIN) { scale = DBL_MANT_DIG; __real__ x = __scalbn (__real__ x, scale); __imag__ x = __scalbn (__imag__ x, scale); } d = __ieee754_hypot (__real__ x, __imag__ x); __real__ result = __ieee754_log (d) - scale * M_LN2; __imag__ result = __ieee754_atan2 (__imag__ x, __real__ x); } else { __imag__ result = __nan (""); if (rcls == FP_INFINITE || icls == FP_INFINITE) /* Real or imaginary part is infinite. */ __real__ result = HUGE_VAL; else __real__ result = __nan (""); } return result; }
int main() { /* REQ-BL-0910 * The log and logf procedures shall return -Inf if the argument x is +-0. */ double x = -0.0; double res = __ieee754_log(x); // x is +-0, the result shall be -inf if (!isinf_double(res)) { __VERIFIER_error(); return 1; } return 0; }
EXPORT(sqInt) primitiveLogN(void) { double rcvr; double result; rcvr = interpreterProxy->stackFloatValue(0); if (interpreterProxy->failed()) { return null; } if (rcvr < 0.0) { return interpreterProxy->primitiveFail(); } result = __ieee754_log(rcvr); if (isnan(result)) { return interpreterProxy->primitiveFail(); } interpreterProxy->pop((interpreterProxy->methodArgumentCount()) + 1); interpreterProxy->pushFloat(result); }
/* wrapper log(x) */ double __log (double x) { if (__builtin_expect (islessequal (x, 0.0), 0) && _LIB_VERSION != _IEEE_) { if (x == 0.0) { feraiseexcept (FE_DIVBYZERO); return __kernel_standard (x, x, 16); /* log(0) */ } else { feraiseexcept (FE_INVALID); return __kernel_standard (x, x, 17); /* log(x<0) */ } } return __ieee754_log (x); }
primitiveLogN(void) { // FloatMathPlugin>>#primitiveLogN double rcvr; double result; rcvr = stackFloatValue(0); if (failed()) { return null; } if (rcvr < 0.0) { return primitiveFail(); } result = __ieee754_log(rcvr); if (isnan(result)) { return primitiveFail(); } pop((methodArgumentCount()) + 1); pushFloat(result); }
/* wrapper logf(x) */ float logf (float x) { #if defined(__UCLIBC_HAS_FENV__) if (__builtin_expect (islessequal (x, 0.0f), 0) && _LIB_VERSION != _IEEE_) { if (x == 0.0f) { feraiseexcept (FE_DIVBYZERO); return __kernel_standard_f (x, x, 116); /* log(0) */ } else { feraiseexcept (FE_INVALID); return __kernel_standard_f (x, x, 117); /* log(x<0) */ } } #endif return (float) __ieee754_log ((double) x); }
/* wrapper log(x) */ double log (double x) { #if defined(__UCLIBC_HAS_FENV__) if (__builtin_expect (islessequal (x, 0.0), 0) && _LIB_VERSION != _IEEE_) { if (x == 0.0) { feraiseexcept (FE_DIVBYZERO); return __kernel_standard (x, x, 16); /* log(0) */ } else { feraiseexcept (FE_INVALID); return __kernel_standard (x, x, 17); /* log(x<0) */ } } #endif /* __UCLIBC_HAS_FENV__ */ return __ieee754_log (x); }
int main() { /* REQ-BL-0920 * The log and logf procedures shall return NaN if the argument x is finite * and less than 0 or x is -Inf. */ double x = __VERIFIER_nondet_double(); if ((x < 0 && isfinite_double(x))) { double res = __ieee754_log(x); // x is < 0 and finite, result shall be NAN if (!isnan_double(res)) { __VERIFIER_error(); return 1; } } return 0; }
double __ieee754_y1 (double x) { double z, s, c, ss, cc, u, v, u1, u2, v1, v2, v3, z2, z4; int32_t hx, ix, lx; EXTRACT_WORDS (hx, lx, x); ix = 0x7fffffff & hx; /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ if (__glibc_unlikely (ix >= 0x7ff00000)) return one / (x + x * x); if (__glibc_unlikely ((ix | lx) == 0)) return -1 / zero; /* -inf and divide by zero exception. */ /* -inf and overflow exception. */; if (__glibc_unlikely (hx < 0)) return zero / (zero * x); if (ix >= 0x40000000) /* |x| >= 2.0 */ { __sincos (x, &s, &c); ss = -s - c; cc = s - c; if (ix < 0x7fe00000) /* make sure x+x not overflow */ { z = __cos (x + x); if ((s * c) > zero) cc = z / ss; else ss = z / cc; } /* y1(x) = sqrt(2/(pi*x))*(p1(x)*sin(x0)+q1(x)*cos(x0)) * where x0 = x-3pi/4 * Better formula: * cos(x0) = cos(x)cos(3pi/4)+sin(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = -1/sqrt(2) * (cos(x) + sin(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ if (ix > 0x48000000) z = (invsqrtpi * ss) / sqrt (x); else { u = pone (x); v = qone (x); z = invsqrtpi * (u * ss + v * cc) / sqrt (x); } return z; } if (__glibc_unlikely (ix <= 0x3c900000)) /* x < 2**-54 */ { z = -tpi / x; if (isinf (z)) __set_errno (ERANGE); return z; } z = x * x; u1 = U0[0] + z * U0[1]; z2 = z * z; u2 = U0[2] + z * U0[3]; z4 = z2 * z2; u = u1 + z2 * u2 + z4 * U0[4]; v1 = one + z * V0[0]; v2 = V0[1] + z * V0[2]; v3 = V0[3] + z * V0[4]; v = v1 + z2 * v2 + z4 * v3; return (x * (u / v) + tpi * (__ieee754_j1 (x) * __ieee754_log (x) - one / x)); }
static double gamma_positive (double x, int *exp2_adj) { int local_signgam; if (x < 0.5) { *exp2_adj = 0; return __ieee754_exp (__ieee754_lgamma_r (x + 1, &local_signgam)) / x; } else if (x <= 1.5) { *exp2_adj = 0; return __ieee754_exp (__ieee754_lgamma_r (x, &local_signgam)); } else if (x < 6.5) { /* Adjust into the range for using exp (lgamma). */ *exp2_adj = 0; double n = __ceil (x - 1.5); double x_adj = x - n; double eps; double prod = __gamma_product (x_adj, 0, n, &eps); return (__ieee754_exp (__ieee754_lgamma_r (x_adj, &local_signgam)) * prod * (1.0 + eps)); } else { double eps = 0; double x_eps = 0; double x_adj = x; double prod = 1; if (x < 12.0) { /* Adjust into the range for applying Stirling's approximation. */ double n = __ceil (12.0 - x); #if FLT_EVAL_METHOD != 0 volatile #endif double x_tmp = x + n; x_adj = x_tmp; x_eps = (x - (x_adj - n)); prod = __gamma_product (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. */ double exp_adj = -eps; double x_adj_int = __round (x_adj); double x_adj_frac = x_adj - x_adj_int; int x_adj_log2; double x_adj_mant = __frexp (x_adj, &x_adj_log2); if (x_adj_mant < M_SQRT1_2) { x_adj_log2--; x_adj_mant *= 2.0; } *exp2_adj = x_adj_log2 * (int) x_adj_int; double ret = (__ieee754_pow (x_adj_mant, x_adj) * __ieee754_exp2 (x_adj_log2 * x_adj_frac) * __ieee754_exp (-x_adj) * __ieee754_sqrt (2 * M_PI / x_adj) / prod); exp_adj += x_eps * __ieee754_log (x); double bsum = gamma_coeff[NCOEFF - 1]; 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 * __expm1 (exp_adj); } }
double __ieee754_lgamma_r(double x, int *signgamp) { double t,y,z,nadj,p,p1,p2,p3,q,r,w; int i,hx,lx,ix; EXTRACT_WORDS(hx,lx,x); /* purge off +-inf, NaN, +-0, and negative arguments */ *signgamp = 1; ix = hx&0x7fffffff; if(ix>=0x7ff00000) return x*x; if((ix|lx)==0) return one/zero; if(ix<0x3b900000) { /* |x|<2**-70, return -log(|x|) */ if(hx<0) { *signgamp = -1; return -__ieee754_log(-x); } else return -__ieee754_log(x); } if(hx<0) { if(ix>=0x43300000) /* |x|>=2**52, must be -integer */ return one/zero; t = sin_pi(x); if(t==zero) return one/zero; /* -integer */ nadj = __ieee754_log(pi/fabs(t*x)); if(t<zero) *signgamp = -1; x = -x; } /* purge off 1 and 2 */ if((((ix-0x3ff00000)|lx)==0)||(((ix-0x40000000)|lx)==0)) r = 0; /* for x < 2.0 */ else if(ix<0x40000000) { if(ix<=0x3feccccc) { /* lgamma(x) = lgamma(x+1)-log(x) */ r = -__ieee754_log(x); if(ix>=0x3FE76944) {y = one-x; i= 0;} else if(ix>=0x3FCDA661) {y= x-(tc-one); i=1;} else {y = x; i=2;} } else { r = zero; if(ix>=0x3FFBB4C3) {y=2.0-x;i=0;} /* [1.7316,2] */ else if(ix>=0x3FF3B4C4) {y=x-tc;i=1;} /* [1.23,1.73] */ else {y=x-one;i=2;} } switch(i) { case 0: z = y*y; p1 = a0+z*(a2+z*(a4+z*(a6+z*(a8+z*a10)))); p2 = z*(a1+z*(a3+z*(a5+z*(a7+z*(a9+z*a11))))); p = y*p1+p2; r += (p-0.5*y); break; case 1: z = y*y; w = z*y; p1 = t0+w*(t3+w*(t6+w*(t9 +w*t12))); /* parallel comp */ p2 = t1+w*(t4+w*(t7+w*(t10+w*t13))); p3 = t2+w*(t5+w*(t8+w*(t11+w*t14))); p = z*p1-(tt-w*(p2+y*p3)); r += (tf + p); break; case 2: p1 = y*(u0+y*(u1+y*(u2+y*(u3+y*(u4+y*u5))))); p2 = one+y*(v1+y*(v2+y*(v3+y*(v4+y*v5)))); r += (-0.5*y + p1/p2); } } else if(ix<0x40200000) { /* x < 8.0 */ i = (int)x; t = zero; y = x-(double)i; p = y*(s0+y*(s1+y*(s2+y*(s3+y*(s4+y*(s5+y*s6)))))); q = one+y*(r1+y*(r2+y*(r3+y*(r4+y*(r5+y*r6))))); r = half*y+p/q; z = one; /* lgamma(1+s) = log(s) + lgamma(s) */ switch(i) { case 7: z *= (y+6.0); /* FALLTHRU */ case 6: z *= (y+5.0); /* FALLTHRU */ case 5: z *= (y+4.0); /* FALLTHRU */ case 4: z *= (y+3.0); /* FALLTHRU */ case 3: z *= (y+2.0); /* FALLTHRU */ r += __ieee754_log(z); break; } /* 8.0 <= x < 2**58 */ } else if (ix < 0x43900000) { t = __ieee754_log(x); z = one/x; y = z*z; w = w0+z*(w1+y*(w2+y*(w3+y*(w4+y*(w5+y*w6))))); r = (x-half)*(t-one)+w; } else /* 2**58 <= x <= inf */ r = x*(__ieee754_log(x)-one); if(hx<0) r = nadj - r; return r; }
__complex__ double __catanh (__complex__ double x) { __complex__ double 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 = __copysign (0.0, __real__ x); __imag__ res = __copysign (M_PI_2, __imag__ x); } else if (rcls == FP_INFINITE || rcls == FP_ZERO) { __real__ res = __copysign (0.0, __real__ x); if (icls >= FP_ZERO) __imag__ res = __copysign (M_PI_2, __imag__ x); else __imag__ res = __nan (""); } else { __real__ res = __nan (""); __imag__ res = __nan (""); } } else if (__glibc_unlikely (rcls == FP_ZERO && icls == FP_ZERO)) { res = x; } else { if (fabs (__real__ x) >= 16.0 / DBL_EPSILON || fabs (__imag__ x) >= 16.0 / DBL_EPSILON) { __imag__ res = __copysign (M_PI_2, __imag__ x); if (fabs (__imag__ x) <= 1.0) __real__ res = 1.0 / __real__ x; else if (fabs (__real__ x) <= 1.0) __real__ res = __real__ x / __imag__ x / __imag__ x; else { double h = __ieee754_hypot (__real__ x / 2.0, __imag__ x / 2.0); __real__ res = __real__ x / h / h / 4.0; } } else { if (fabs (__real__ x) == 1.0 && fabs (__imag__ x) < DBL_EPSILON * DBL_EPSILON) __real__ res = (__copysign (0.5, __real__ x) * (M_LN2 - __ieee754_log (fabs (__imag__ x)))); else { double i2 = 0.0; if (fabs (__imag__ x) >= DBL_EPSILON * DBL_EPSILON) i2 = __imag__ x * __imag__ x; double num = 1.0 + __real__ x; num = i2 + num * num; double den = 1.0 - __real__ x; den = i2 + den * den; double f = num / den; if (f < 0.5) __real__ res = 0.25 * __ieee754_log (f); else { num = 4.0 * __real__ x; __real__ res = 0.25 * __log1p (num / den); } } double absx, absy, den; absx = fabs (__real__ x); absy = fabs (__imag__ x); if (absx < absy) { double t = absx; absx = absy; absy = t; } if (absy < DBL_EPSILON / 2.0) { den = (1.0 - absx) * (1.0 + absx); if (den == -0.0) den = 0.0; } else if (absx >= 1.0) den = (1.0 - absx) * (1.0 + absx) - absy * absy; else if (absx >= 0.75 || absy >= 0.5) den = -__x2y2m1 (absx, absy); else den = (1.0 - absx) * (1.0 + absx) - absy * absy; __imag__ res = 0.5 * __ieee754_atan2 (2.0 * __imag__ x, den); } math_check_force_underflow_complex (res); } return res; }
double __ieee754_y0(double x) { double z, s,c,ss,cc,u,v,z2,z4,z6,u1,u2,u3,v1,v2; int32_t hx,ix,lx; EXTRACT_WORDS(hx,lx,x); ix = 0x7fffffff&hx; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ if(ix>=0x7ff00000) return one/(x+x*x); if((ix|lx)==0) return -HUGE_VAL+x; /* -inf and overflow exception. */ if(hx<0) return zero/(zero*x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ /* y0(x) = sqrt(2/(pi*x))*(p0(x)*sin(x0)+q0(x)*cos(x0)) * where x0 = x-pi/4 * Better formula: * cos(x0) = cos(x)cos(pi/4)+sin(x)sin(pi/4) * = 1/sqrt(2) * (sin(x) + cos(x)) * sin(x0) = sin(x)cos(3pi/4)-cos(x)sin(3pi/4) * = 1/sqrt(2) * (sin(x) - cos(x)) * To avoid cancellation, use * sin(x) +- cos(x) = -cos(2x)/(sin(x) -+ cos(x)) * to compute the worse one. */ __sincos (x, &s, &c); ss = s-c; cc = s+c; /* * j0(x) = 1/sqrt(pi) * (P(0,x)*cc - Q(0,x)*ss) / sqrt(x) * y0(x) = 1/sqrt(pi) * (P(0,x)*ss + Q(0,x)*cc) / sqrt(x) */ if(ix<0x7fe00000) { /* make sure x+x not overflow */ z = -__cos(x+x); if ((s*c)<zero) cc = z/ss; else ss = z/cc; } if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrt(x); else { u = pzero(x); v = qzero(x); z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrt(x); } return z; } if(ix<=0x3e400000) { /* x < 2**-27 */ return(U[0] + tpi*__ieee754_log(x)); } z = x*x; #ifdef DO_NOT_USE_THIS u = u00+z*(u01+z*(u02+z*(u03+z*(u04+z*(u05+z*u06))))); v = one+z*(v01+z*(v02+z*(v03+z*v04))); #else u1 = U[0]+z*U[1]; z2=z*z; u2 = U[2]+z*U[3]; z4=z2*z2; u3 = U[4]+z*U[5]; z6=z4*z2; u = u1 + z2*u2 + z4*u3 + z6*U[6]; v1 = one+z*V[0]; v2 = V[1]+z*V[2]; v = v1 + z2*v2 + z4*V[3]; #endif return(u/v + tpi*(__ieee754_j0(x)*__ieee754_log(x))); }
__complex__ double __kernel_casinh (__complex__ double x, int adj) { __complex__ double res; double rx, ix; __complex__ double y; /* Avoid cancellation by reducing to the first quadrant. */ rx = fabs (__real__ x); ix = fabs (__imag__ x); if (rx >= 1.0 / DBL_EPSILON || ix >= 1.0 / DBL_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) { double t = __real__ y; __real__ y = __copysign (__imag__ y, __imag__ x); __imag__ y = t; } res = __clog (y); __real__ res += M_LN2; } else if (rx >= 0.5 && ix < DBL_EPSILON / 8.0) { double s = __ieee754_hypot (1.0, rx); __real__ res = __ieee754_log (rx + s); if (adj) __imag__ res = __ieee754_atan2 (s, __imag__ x); else __imag__ res = __ieee754_atan2 (ix, s); } else if (rx < DBL_EPSILON / 8.0 && ix >= 1.5) { double s = __ieee754_sqrt ((ix + 1.0) * (ix - 1.0)); __real__ res = __ieee754_log (ix + s); if (adj) __imag__ res = __ieee754_atan2 (rx, __copysign (s, __imag__ x)); else __imag__ res = __ieee754_atan2 (s, rx); } else if (ix > 1.0 && ix < 1.5 && rx < 0.5) { if (rx < DBL_EPSILON * DBL_EPSILON) { double ix2m1 = (ix + 1.0) * (ix - 1.0); double s = __ieee754_sqrt (ix2m1); __real__ res = __log1p (2.0 * (ix2m1 + ix * s)) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (rx, __copysign (s, __imag__ x)); else __imag__ res = __ieee754_atan2 (s, rx); } else { double ix2m1 = (ix + 1.0) * (ix - 1.0); double rx2 = rx * rx; double f = rx2 * (2.0 + rx2 + 2.0 * ix * ix); double d = __ieee754_sqrt (ix2m1 * ix2m1 + f); double dp = d + ix2m1; double dm = f / dp; double r1 = __ieee754_sqrt ((dm + rx2) / 2.0); double r2 = rx * ix / r1; __real__ res = __log1p (rx2 + dp + 2.0 * (rx * r1 + ix * r2)) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (rx + r1, __copysign (ix + r2, __imag__ x)); else __imag__ res = __ieee754_atan2 (ix + r2, rx + r1); } } else if (ix == 1.0 && rx < 0.5) { if (rx < DBL_EPSILON / 8.0) { __real__ res = __log1p (2.0 * (rx + __ieee754_sqrt (rx))) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (__ieee754_sqrt (rx), __copysign (1.0, __imag__ x)); else __imag__ res = __ieee754_atan2 (1.0, __ieee754_sqrt (rx)); } else { double d = rx * __ieee754_sqrt (4.0 + rx * rx); double s1 = __ieee754_sqrt ((d + rx * rx) / 2.0); double s2 = __ieee754_sqrt ((d - rx * rx) / 2.0); __real__ res = __log1p (rx * rx + d + 2.0 * (rx * s1 + s2)) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (rx + s1, __copysign (1.0 + s2, __imag__ x)); else __imag__ res = __ieee754_atan2 (1.0 + s2, rx + s1); } } else if (ix < 1.0 && rx < 0.5) { if (ix >= DBL_EPSILON) { if (rx < DBL_EPSILON * DBL_EPSILON) { double onemix2 = (1.0 + ix) * (1.0 - ix); double s = __ieee754_sqrt (onemix2); __real__ res = __log1p (2.0 * rx / s) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (s, __imag__ x); else __imag__ res = __ieee754_atan2 (ix, s); } else { double onemix2 = (1.0 + ix) * (1.0 - ix); double rx2 = rx * rx; double f = rx2 * (2.0 + rx2 + 2.0 * ix * ix); double d = __ieee754_sqrt (onemix2 * onemix2 + f); double dp = d + onemix2; double dm = f / dp; double r1 = __ieee754_sqrt ((dp + rx2) / 2.0); double r2 = rx * ix / r1; __real__ res = __log1p (rx2 + dm + 2.0 * (rx * r1 + ix * r2)) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (rx + r1, __copysign (ix + r2, __imag__ x)); else __imag__ res = __ieee754_atan2 (ix + r2, rx + r1); } } else { double s = __ieee754_hypot (1.0, rx); __real__ res = __log1p (2.0 * rx * (rx + s)) / 2.0; if (adj) __imag__ res = __ieee754_atan2 (s, __imag__ x); else __imag__ res = __ieee754_atan2 (ix, s); } math_check_force_underflow_nonneg (__real__ res); } else { __real__ y = (rx - ix) * (rx + ix) + 1.0; __imag__ y = 2.0 * rx * ix; y = __csqrt (y); __real__ y += rx; __imag__ y += ix; if (adj) { double t = __real__ y; __real__ y = __copysign (__imag__ y, __imag__ x); __imag__ y = t; } res = __clog (y); } /* Give results the correct sign for the original argument. */ __real__ res = __copysign (__real__ res, __real__ x); __imag__ res = __copysign (__imag__ res, (adj ? 1.0 : __imag__ x)); return res; }
Err mathlib_log(UInt16 refnum, double x, double *result) { #pragma unused(refnum) *result = __ieee754_log(x); return mlErrNone; }
double log(double x) /* wrapper log */ { return __ieee754_log(x); }