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); }
float __ieee754_y1f(float x) { float z, s,c,ss,cc,u,v; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; /* if Y1(NaN) is NaN, Y1(-inf) is NaN, Y1(inf) is 0 */ if(__builtin_expect(ix>=0x7f800000, 0)) return one/(x+x*x); if(__builtin_expect(ix==0, 0)) return -HUGE_VALF+x; /* -inf and overflow exception. */ if(__builtin_expect(hx<0, 0)) return zero/(zero*x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ SET_RESTORE_ROUNDF (FE_TONEAREST); __sincosf (x, &s, &c); ss = -s-c; cc = s-c; if(ix<0x7f000000) { /* make sure x+x not overflow */ z = __cosf(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_sqrtf(x); else { u = ponef(x); v = qonef(x); z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x); } return z; } if(__builtin_expect(ix<=0x33000000, 0)) { /* x < 2**-25 */ z = -tpi / x; if (__isinff (z)) __set_errno (ERANGE); return z; } 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_j1f(x)*__ieee754_logf(x)-one/x)); }
float __ieee754_y0f(float x) { float z, s,c,ss,cc,u,v; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = 0x7fffffff&hx; /* Y0(NaN) is NaN, y0(-inf) is Nan, y0(inf) is 0, y0(0) is -inf. */ if(ix>=0x7f800000) return one/(x+x*x); if(ix==0) return -HUGE_VALF+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. */ __sincosf (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<0x7f000000) { /* make sure x+x not overflow */ z = -__cosf(x+x); if ((s*c)<zero) cc = z/ss; else ss = z/cc; } if(ix>0x48000000) z = (invsqrtpi*ss)/__ieee754_sqrtf(x); else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*ss+v*cc)/__ieee754_sqrtf(x); } return z; } if(ix<=0x32000000) { /* x < 2**-27 */ return(u00 + tpi*__ieee754_logf(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_j0f(x)*__ieee754_logf(x))); }
float sqrtf(float x) /* wrapper sqrtf */ { #ifdef _IEEE_LIBM return __ieee754_sqrtf(x); #else float z; z = __ieee754_sqrtf(x); if(_LIB_VERSION == _IEEE_ || isnanf(x)) return z; if(x<(float)0.0) { /* sqrtf(negative) */ return (float)__kernel_standard((double)x,(double)x,126); } else return z; #endif }
/* wrapper sqrtf */ float __sqrtf (float x) { if (__builtin_expect (isless (x, 0.0f), 0) && _LIB_VERSION != _IEEE_) return __kernel_standard_f (x, x, 126); /* sqrt(negative) */ return __ieee754_sqrtf (x); }
float __ieee754_j0f(float x) { float z, s,c,ss,cc,r,u,v; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) return one/(x*x); x = fabsf(x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ __sincosf (x, &s, &c); ss = s-c; cc = s+c; if(ix<0x7f000000) { /* make sure x+x not overflow */ z = -__cosf(x+x); if ((s*c)<zero) cc = z/ss; else ss = z/cc; } /* * 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>0x48000000) z = (invsqrtpi*cc)/__ieee754_sqrtf(x); else { u = pzerof(x); v = qzerof(x); z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(x); } return z; } if(ix<0x39000000) { /* |x| < 2**-13 */ math_force_eval(huge+x); /* raise inexact if x != 0 */ if(ix<0x32000000) return one; /* |x|<2**-27 */ else return one - (float)0.25*x*x; } z = x*x; r = z*(R02+z*(R03+z*(R04+z*R05))); s = one+z*(S01+z*(S02+z*(S03+z*S04))); if(ix < 0x3F800000) { /* |x| < 1.00 */ return one + z*((float)-0.25+(r/s)); } else { u = (float)0.5*x; return((one+u)*(one-u)+z*(r/s)); } }
//------------------------------------------------------------------------------ float Cmath::__ieee754_acoshf( float x ) { static const float one = 1.0; static const float ln2 = 6.9314718246e-01; // 0x3f317218 float t; Cmp_signed__int32 hx; get_float_word( hx, x ); if( hx < 0x3f800000 ) { // x < 1 return ( x - x ) / ( x - x ); } else if( hx >= 0x4d800000 ) { // x > 2**28 if( !uword_isfinite( hx ) ) { // x is inf of NaN return x + x; } else { return __ieee754_logf( x ) + ln2; // acosh(huge)=log(2x) } } else if ( hx == 0x3f800000 ) { return 0.0; // acosh(1) = 0 } else if ( hx > 0x40000000 ) { // 2**28 > x > 2 t = x * x; return __ieee754_logf( (float)2.0 * x - one / ( x + __ieee754_sqrtf( t - one ) ) ); } else { // 1<x<2 t = x - one; return log1pf( t + __ieee754_sqrtf( (float)2.0 * t + t * t ) ); } }
float __ieee754_acosf(float x) { float z,p,q,r,w,s,c,df; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix==0x3f800000) { /* |x|==1 */ if(hx>0) return 0.0; /* acos(1) = 0 */ else return pi+(float)2.0*pio2_lo; /* acos(-1)= pi */ } else if(ix>0x3f800000) { /* |x| >= 1 */ return (x-x)/(x-x); /* acos(|x|>1) is NaN */ } if(ix<0x3f000000) { /* |x| < 0.5 */ if(ix<=0x23000000) return pio2_hi+pio2_lo;/*if|x|<2**-57*/ z = x*x; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); r = p/q; return pio2_hi - (x - (pio2_lo-x*r)); } else if (hx<0) { /* x < -0.5 */ z = (one+x)*(float)0.5; p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); s = __ieee754_sqrtf(z); r = p/q; w = r*s-pio2_lo; return pi - (float)2.0*(s+w); } else { /* x > 0.5 */ int32_t idf; z = (one-x)*(float)0.5; s = __ieee754_sqrtf(z); df = s; GET_FLOAT_WORD(idf,df); SET_FLOAT_WORD(df,idf&0xfffff000); c = (z-df*df)/(s+df); p = z*(pS0+z*(pS1+z*(pS2+z*(pS3+z*(pS4+z*pS5))))); q = one+z*(qS1+z*(qS2+z*(qS3+z*qS4))); r = p/q; w = r*s+c; return (float)2.0*(df+w); } }
float __ieee754_j1f(float x) { float z, s,c,ss,cc,r,u,v,y; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(__builtin_expect(ix>=0x7f800000, 0)) return one/x; y = fabsf(x); if(ix >= 0x40000000) { /* |x| >= 2.0 */ __sincosf (y, &s, &c); ss = -s-c; cc = s-c; if(ix<0x7f000000) { /* make sure y+y not overflow */ z = __cosf(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)/__ieee754_sqrtf(y); else { u = ponef(y); v = qonef(y); z = invsqrtpi*(u*cc-v*ss)/__ieee754_sqrtf(y); } if(hx<0) return -z; else return z; } if(__builtin_expect(ix<0x32000000, 0)) { /* |x|<2**-27 */ if(huge+x>one) return (float)0.5*x;/* inexact if x!=0 necessary */ } z = x*x; r = z*(r00+z*(r01+z*(r02+z*r03))); s = one+z*(s01+z*(s02+z*(s03+z*(s04+z*s05)))); r *= x; return(x*(float)0.5+r/s); }
float asinhf(float x) { float t,w; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix>=0x7f800000) return x+x; /* x is inf or NaN */ if(ix< 0x31800000) { /* |x|<2**-28 */ if(huge+x>one) return x; /* return x inexact except 0 */ } if(ix>0x4d800000) { /* |x| > 2**28 */ w = __ieee754_logf(fabsf(x))+ln2; } else if (ix>0x40000000) { /* 2**28 > |x| > 2.0 */ t = fabsf(x); w = __ieee754_logf((float)2.0*t+one/(__ieee754_sqrtf(x*x+one)+t)); } else { /* 2.0 > |x| > 2**-28 */ t = x*x; w =log1pf(fabsf(x)+t/(one+__ieee754_sqrtf(one+t))); } if(hx>0) return w; else return -w; }
float __ieee754_acoshf(float x) { float t; int32_t hx; GET_FLOAT_WORD(hx,x); if(hx<0x3f800000) { /* x < 1 */ return (x-x)/(x-x); } else if(hx >=0x4d800000) { /* x > 2**28 */ if(hx >=0x7f800000) { /* x is inf of NaN */ return x+x; } else return __ieee754_logf(x)+ln2; /* acosh(huge)=log(2x) */ } else if (hx==0x3f800000) { return 0.0; /* acosh(1) = 0 */ } else if (hx > 0x40000000) { /* 2**28 > x > 2 */ t=x*x; return __ieee754_logf((float)2.0*x-one/(x+__ieee754_sqrtf(t-one))); } else { /* 1<x<2 */ t = x-one; return log1pf(t+__ieee754_sqrtf((float)2.0*t+t*t)); } }
float __ieee754_asinf(float x) { float t,w,p,q,c,r,s; int32_t hx,ix; t = 0; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix==0x3f800000) { /* asin(1)=+-pi/2 with inexact */ return x*pio2_hi+x*pio2_lo; } else if(ix> 0x3f800000) { /* |x|>= 1 */ return (x-x)/(x-x); /* asin(|x|>1) is NaN */ } else if (ix<0x3f000000) { /* |x|<0.5 */ if(ix<0x32000000) { /* if |x| < 2**-27 */ if(huge+x>one) return x;/* return x with inexact if x!=0*/ } else t = x*x; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); w = p/q; return x+x*w; } /* 1> |x|>= 0.5 */ w = one-fabsf(x); t = w*(float)0.5; p = t*(pS0+t*(pS1+t*(pS2+t*(pS3+t*(pS4+t*pS5))))); q = one+t*(qS1+t*(qS2+t*(qS3+t*qS4))); s = __ieee754_sqrtf(t); if(ix>=0x3F79999A) { /* if |x| > 0.975 */ w = p/q; t = pio2_hi-((float)2.0*(s+s*w)-pio2_lo); } else { int32_t iw; w = s; GET_FLOAT_WORD(iw,w); SET_FLOAT_WORD(w,iw&0xfffff000); c = (t-w*w)/(s+w); r = p/q; p = (float)2.0*s*r-(pio2_lo-(float)2.0*c); q = pio4_hi-(float)2.0*w; t = pio4_hi-(p-q); } if(hx>0) return t; else return -t; }
float __ieee754_asinf(float x) { float t,w,p,q,c,r,s; int32_t hx,ix; GET_FLOAT_WORD(hx,x); ix = hx&0x7fffffff; if(ix==0x3f800000) { /* asin(1)=+-pi/2 with inexact */ return x*pio2_hi+x*pio2_lo; } else if(ix> 0x3f800000) { /* |x|>= 1 */ return (x-x)/(x-x); /* asin(|x|>1) is NaN */ } else if (ix<0x3f000000) { /* |x|<0.5 */ if(ix<0x32000000) { /* if |x| < 2**-27 */ if(huge+x>one) return x;/* return x with inexact if x!=0*/ } else { t = x*x; w = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); return x+x*w; } } /* 1> |x|>= 0.5 */ w = one-fabsf(x); t = w*0.5f; p = t * (p0 + t * (p1 + t * (p2 + t * (p3 + t * p4)))); s = __ieee754_sqrtf(t); if(ix>=0x3F79999A) { /* if |x| > 0.975 */ t = pio2_hi-(2.0f*(s+s*p)-pio2_lo); } else { int32_t iw; w = s; GET_FLOAT_WORD(iw,w); SET_FLOAT_WORD(w,iw&0xfffff000); c = (t-w*w)/(s+w); r = p; p = 2.0f*s*r-(pio2_lo-2.0f*c); q = pio4_hi-2.0f*w; t = pio4_hi-(p-q); } if(hx>0) return t; else return -t; }
__complex__ float __csqrtf (__complex__ float x) { __complex__ float 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_VALF; __imag__ res = __imag__ x; } else if (rcls == FP_INFINITE) { if (__real__ x < 0.0) { __real__ res = icls == FP_NAN ? __nanf ("") : 0; __imag__ res = __copysignf (HUGE_VALF, __imag__ x); } else { __real__ res = __real__ x; __imag__ res = (icls == FP_NAN ? __nanf ("") : __copysignf (0.0, __imag__ x)); } } else { __real__ res = __nanf (""); __imag__ res = __nanf (""); } } else { if (__builtin_expect (icls == FP_ZERO, 0)) { if (__real__ x < 0.0) { __real__ res = 0.0; __imag__ res = __copysignf (__ieee754_sqrtf (-__real__ x), __imag__ x); } else { __real__ res = fabsf (__ieee754_sqrtf (__real__ x)); __imag__ res = __copysignf (0.0, __imag__ x); } } else if (__builtin_expect (rcls == FP_ZERO, 0)) { float r; if (fabsf (__imag__ x) >= 2.0f * FLT_MIN) r = __ieee754_sqrtf (0.5f * fabsf (__imag__ x)); else r = 0.5f * __ieee754_sqrtf (2.0f * fabsf (__imag__ x)); __real__ res = r; __imag__ res = __copysignf (r, __imag__ x); } else { float d, r, s; int scale = 0; if (fabsf (__real__ x) > FLT_MAX / 4.0f) { scale = 1; __real__ x = __scalbnf (__real__ x, -2 * scale); __imag__ x = __scalbnf (__imag__ x, -2 * scale); } else if (fabsf (__imag__ x) > FLT_MAX / 4.0f) { scale = 1; if (fabsf (__real__ x) >= 4.0f * FLT_MIN) __real__ x = __scalbnf (__real__ x, -2 * scale); else __real__ x = 0.0f; __imag__ x = __scalbnf (__imag__ x, -2 * scale); } else if (fabsf (__real__ x) < FLT_MIN && fabsf (__imag__ x) < FLT_MIN) { scale = -(FLT_MANT_DIG / 2); __real__ x = __scalbnf (__real__ x, -2 * scale); __imag__ x = __scalbnf (__imag__ x, -2 * scale); } d = __ieee754_hypotf (__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_sqrtf (0.5f * (d + __real__ x)); s = 0.5f * (__imag__ x / r); } else { s = __ieee754_sqrtf (0.5f * (d - __real__ x)); r = fabsf (0.5f * (__imag__ x / s)); } if (scale) { r = __scalbnf (r, scale); s = __scalbnf (s, scale); } __real__ res = r; __imag__ res = __copysignf (s, __imag__ x); } } return res; }
__complex__ float __cacoshf (__complex__ float x) { __complex__ float res; int rcls = fpclassify (__real__ x); int icls = fpclassify (__imag__ x); if (rcls <= FP_INFINITE || icls <= FP_INFINITE) { if (icls == FP_INFINITE) { __real__ res = HUGE_VALF; if (rcls == FP_NAN) __imag__ res = __nanf (""); else __imag__ res = __copysignf ((rcls == FP_INFINITE ? (__real__ x < 0.0 ? M_PI - M_PI_4 : M_PI_4) : M_PI_2), __imag__ x); } else if (rcls == FP_INFINITE) { __real__ res = HUGE_VALF; if (icls >= FP_ZERO) __imag__ res = __copysignf (signbit (__real__ x) ? M_PI : 0.0, __imag__ x); else __imag__ res = __nanf (""); } else { __real__ res = __nanf (""); __imag__ res = __nanf (""); } } else if (rcls == FP_ZERO && icls == FP_ZERO) { __real__ res = 0.0; __imag__ res = __copysignf (M_PI_2, __imag__ x); } else { #if 1 __complex__ float y; __real__ y = (__real__ x - __imag__ x) * (__real__ x + __imag__ x) - 1.0; __imag__ y = 2.0 * __real__ x * __imag__ x; y = __csqrtf (y); if (__real__ x < 0.0) y = -y; __real__ y += __real__ x; __imag__ y += __imag__ x; res = __clogf (y); #else float re2 = __real__ x * __real__ x; float im2 = __imag__ x * __imag__ x; float sq = re2 - im2 - 1.0; float ro = __ieee754_sqrtf (sq * sq + 4 * re2 * im2); float a = __ieee754_sqrtf ((sq + ro) / 2.0); float b = __ieee754_sqrtf ((-sq + ro) / 2.0); __real__ res = 0.5 * __ieee754_logf (re2 + __real__ x * 2 * a + im2 + __imag__ x * 2 * b + ro); __imag__ res = __ieee754_atan2f (__imag__ x + b, __real__ x + a); #endif /* We have to use the positive branch. */ if (__real__ res < 0.0) res = -res; } return res; }
__complex__ float __csqrtf (__complex__ float x) { __complex__ float res; int rcls = fpclassify (__real__ x); int icls = fpclassify (__imag__ x); if (rcls <= FP_INFINITE || icls <= FP_INFINITE) { if (icls == FP_INFINITE) { __real__ res = HUGE_VALF; __imag__ res = __imag__ x; } else if (rcls == FP_INFINITE) { if (__real__ x < 0.0) { __real__ res = icls == FP_NAN ? __nanf ("") : 0; __imag__ res = __copysignf (HUGE_VALF, __imag__ x); } else { __real__ res = __real__ x; __imag__ res = (icls == FP_NAN ? __nanf ("") : __copysignf (0.0, __imag__ x)); } } else { __real__ res = __nanf (""); __imag__ res = __nanf (""); } } else { if (icls == FP_ZERO) { if (__real__ x < 0.0) { __real__ res = 0.0; __imag__ res = __copysignf (__ieee754_sqrtf (-__real__ x), __imag__ x); } else { __real__ res = fabsf (__ieee754_sqrtf (__real__ x)); __imag__ res = __copysignf (0.0, __imag__ x); } } else if (rcls == FP_ZERO) { float r = __ieee754_sqrtf (0.5 * fabsf (__imag__ x)); __real__ res = __copysignf (r, __imag__ x); __imag__ res = r; } else { float d, r, s; d = __ieee754_hypotf (__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_sqrtf (0.5f * d + 0.5f * __real__ x); s = (0.5f * __imag__ x) / r; } else { s = __ieee754_sqrtf (0.5f * d - 0.5f * __real__ x); r = fabsf ((0.5f * __imag__ x) / s); } __real__ res = r; __imag__ res = __copysignf (s, __imag__ x); } } return res; }
__complex__ float __kernel_casinhf (__complex__ float x, int adj) { __complex__ float res; float rx, ix; __complex__ float y; /* Avoid cancellation by reducing to the first quadrant. */ rx = fabsf (__real__ x); ix = fabsf (__imag__ x); if (rx >= 1.0f / FLT_EPSILON || ix >= 1.0f / FLT_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) { float t = __real__ y; __real__ y = __copysignf (__imag__ y, __imag__ x); __imag__ y = t; } res = __clogf (y); __real__ res += (float) M_LN2; } else if (rx >= 0.5f && ix < FLT_EPSILON / 8.0f) { float s = __ieee754_hypotf (1.0f, rx); __real__ res = __ieee754_logf (rx + s); if (adj) __imag__ res = __ieee754_atan2f (s, __imag__ x); else __imag__ res = __ieee754_atan2f (ix, s); } else if (rx < FLT_EPSILON / 8.0f && ix >= 1.5f) { float s = __ieee754_sqrtf ((ix + 1.0f) * (ix - 1.0f)); __real__ res = __ieee754_logf (ix + s); if (adj) __imag__ res = __ieee754_atan2f (rx, __copysignf (s, __imag__ x)); else __imag__ res = __ieee754_atan2f (s, rx); } else if (ix > 1.0f && ix < 1.5f && rx < 0.5f) { if (rx < FLT_EPSILON * FLT_EPSILON) { float ix2m1 = (ix + 1.0f) * (ix - 1.0f); float s = __ieee754_sqrtf (ix2m1); __real__ res = __log1pf (2.0f * (ix2m1 + ix * s)) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (rx, __copysignf (s, __imag__ x)); else __imag__ res = __ieee754_atan2f (s, rx); } else { float ix2m1 = (ix + 1.0f) * (ix - 1.0f); float rx2 = rx * rx; float f = rx2 * (2.0f + rx2 + 2.0f * ix * ix); float d = __ieee754_sqrtf (ix2m1 * ix2m1 + f); float dp = d + ix2m1; float dm = f / dp; float r1 = __ieee754_sqrtf ((dm + rx2) / 2.0f); float r2 = rx * ix / r1; __real__ res = __log1pf (rx2 + dp + 2.0f * (rx * r1 + ix * r2)) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (rx + r1, __copysignf (ix + r2, __imag__ x)); else __imag__ res = __ieee754_atan2f (ix + r2, rx + r1); } } else if (ix == 1.0f && rx < 0.5f) { if (rx < FLT_EPSILON / 8.0f) { __real__ res = __log1pf (2.0f * (rx + __ieee754_sqrtf (rx))) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (__ieee754_sqrtf (rx), __copysignf (1.0f, __imag__ x)); else __imag__ res = __ieee754_atan2f (1.0f, __ieee754_sqrtf (rx)); } else { float d = rx * __ieee754_sqrtf (4.0f + rx * rx); float s1 = __ieee754_sqrtf ((d + rx * rx) / 2.0f); float s2 = __ieee754_sqrtf ((d - rx * rx) / 2.0f); __real__ res = __log1pf (rx * rx + d + 2.0f * (rx * s1 + s2)) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (rx + s1, __copysignf (1.0f + s2, __imag__ x)); else __imag__ res = __ieee754_atan2f (1.0f + s2, rx + s1); } } else if (ix < 1.0f && rx < 0.5f) { if (ix >= FLT_EPSILON) { if (rx < FLT_EPSILON * FLT_EPSILON) { float onemix2 = (1.0f + ix) * (1.0f - ix); float s = __ieee754_sqrtf (onemix2); __real__ res = __log1pf (2.0f * rx / s) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (s, __imag__ x); else __imag__ res = __ieee754_atan2f (ix, s); } else { float onemix2 = (1.0f + ix) * (1.0f - ix); float rx2 = rx * rx; float f = rx2 * (2.0f + rx2 + 2.0f * ix * ix); float d = __ieee754_sqrtf (onemix2 * onemix2 + f); float dp = d + onemix2; float dm = f / dp; float r1 = __ieee754_sqrtf ((dp + rx2) / 2.0f); float r2 = rx * ix / r1; __real__ res = __log1pf (rx2 + dm + 2.0f * (rx * r1 + ix * r2)) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (rx + r1, __copysignf (ix + r2, __imag__ x)); else __imag__ res = __ieee754_atan2f (ix + r2, rx + r1); } } else { float s = __ieee754_hypotf (1.0f, rx); __real__ res = __log1pf (2.0f * rx * (rx + s)) / 2.0f; if (adj) __imag__ res = __ieee754_atan2f (s, __imag__ x); else __imag__ res = __ieee754_atan2f (ix, s); } if (__real__ res < FLT_MIN) { volatile float force_underflow = __real__ res * __real__ res; (void) force_underflow; } } else { __real__ y = (rx - ix) * (rx + ix) + 1.0f; __imag__ y = 2.0f * rx * ix; y = __csqrtf (y); __real__ y += rx; __imag__ y += ix; if (adj) { float t = __real__ y; __real__ y = __copysignf (__imag__ y, __imag__ x); __imag__ y = t; } res = __clogf (y); } /* Give results the correct sign for the original argument. */ __real__ res = __copysignf (__real__ res, __real__ x); __imag__ res = __copysignf (__imag__ res, (adj ? 1.0f : __imag__ x)); return res; }
//------------------------------------------------------------------------------ float Cmath::__ieee754_hypotf( float x, float y ) { float a = x, b = y, t1, t2, y1, y2, w; Cmp_signed__int32 j, k, ha, hb; get_float_word( ha, x ); ha &= 0x7fffffffL; get_float_word( hb, y ); hb &= 0x7fffffffL; if( hb > ha ) { a = y; b = x; j = ha; ha = hb; hb = j; } else { a = x; b = y; } set_float_word( a, ha ); // a <- |a| set_float_word( b, hb ); // b <- |b| if( ( ha - hb ) > 0xf000000L ) { return a + b; // x/y > 2**30 } k = 0; if( ha > 0x58800000L ) { // a>2**50 if( !uword_isfinite( ha ) ) { // Inf or NaN w = a + b; // for sNaN if( uword_is_infinite( ha ) ) { w = a; } if( uword_is_infinite( hb ) ) { w = b; } return w; } // scale a and b by 2**-68 ha -= 0x22000000L; hb -= 0x22000000L; k += 68; set_float_word( a, ha ); set_float_word( b, hb ); } if( hb < 0x26800000L ) { // b < 2**-50 if( uword_is_zero( hb ) ) { return a; } else if( uword_is_subnormal( hb ) ) { set_float_word( t1, 0x7e800000L ); // t1=2^126 b *= t1; a *= t1; k -= 126; } else { // scale a and b by 2^68 ha += 0x22000000; // a *= 2^68 hb += 0x22000000; // b *= 2^68 k -= 68; set_float_word( a, ha ); set_float_word( b, hb ); } } // medium size a and b w = a - b; if( w > b ) { set_float_word( t1, ha & 0xfffff000L ); t2 = a - t1; w = __ieee754_sqrtf( t1 * t1 - ( b * (-b) - t2 * ( a + t1 ) ) ); } else { a = a + a; set_float_word( y1, hb & 0xfffff000L ); y2 = b - y1; set_float_word( t1, ha + 0x00800000L ); t2 = a - t1; w = __ieee754_sqrtf( t1 * y1 - ( w * (-w) - ( t1 * y2 + t2 * b ) ) ); } if( k != 0 ) { set_float_word( t1, 0x3f800000L + ( k << 23 ) ); return t1 * w; } else { return w; } }
float __ieee754_hypotf(float x, float y) { float a=x,b=y,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_FLOAT_WORD(ha,x); ha &= 0x7fffffff; GET_FLOAT_WORD(hb,y); hb &= 0x7fffffff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} SET_FLOAT_WORD(a,ha); /* a <- |a| */ SET_FLOAT_WORD(b,hb); /* b <- |b| */ if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ k=0; if(ha > 0x58800000) { /* a>2**50 */ if(ha >= 0x7f800000) { /* Inf or NaN */ w = a+b; /* for sNaN */ if(ha == 0x7f800000) w = a; if(hb == 0x7f800000) w = b; return w; } /* scale a and b by 2**-60 */ ha -= 0x5d800000; hb -= 0x5d800000; k += 60; SET_FLOAT_WORD(a,ha); SET_FLOAT_WORD(b,hb); } if(hb < 0x26800000) { /* b < 2**-50 */ if(hb <= 0x007fffff) { /* subnormal b or 0 */ if(hb==0) return a; SET_FLOAT_WORD(t1,0x3f000000); /* t1=2^126 */ b *= t1; a *= t1; k -= 126; } else { /* scale a and b by 2^60 */ ha += 0x5d800000; /* a *= 2^60 */ hb += 0x5d800000; /* b *= 2^60 */ k -= 60; SET_FLOAT_WORD(a,ha); SET_FLOAT_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { SET_FLOAT_WORD(t1,ha&0xfffff000); t2 = a-t1; w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; SET_FLOAT_WORD(y1,hb&0xfffff000); y2 = b - y1; SET_FLOAT_WORD(t1,ha+0x00800000); t2 = a - t1; w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); return t1*w; } else return w; }
OLM_DLLEXPORT float __ieee754_hypotf(float x, float y) { float a,b,t1,t2,y1,y2,w; int32_t j,k,ha,hb; GET_FLOAT_WORD(ha,x); ha &= 0x7fffffff; GET_FLOAT_WORD(hb,y); hb &= 0x7fffffff; if(hb > ha) {a=y;b=x;j=ha; ha=hb;hb=j;} else {a=x;b=y;} a = fabsf(a); b = fabsf(b); if((ha-hb)>0xf000000) {return a+b;} /* x/y > 2**30 */ k=0; if(ha > 0x58800000) { /* a>2**50 */ if(ha >= 0x7f800000) { /* Inf or NaN */ /* Use original arg order iff result is NaN; quieten sNaNs. */ w = fabsf(x+0.0F)-fabsf(y+0.0F); if(ha == 0x7f800000) w = a; if(hb == 0x7f800000) w = b; return w; } /* scale a and b by 2**-68 */ ha -= 0x22000000; hb -= 0x22000000; k += 68; SET_FLOAT_WORD(a,ha); SET_FLOAT_WORD(b,hb); } if(hb < 0x26800000) { /* b < 2**-50 */ if(hb <= 0x007fffff) { /* subnormal b or 0 */ if(hb==0) return a; SET_FLOAT_WORD(t1,0x7e800000); /* t1=2^126 */ b *= t1; a *= t1; k -= 126; } else { /* scale a and b by 2^68 */ ha += 0x22000000; /* a *= 2^68 */ hb += 0x22000000; /* b *= 2^68 */ k -= 68; SET_FLOAT_WORD(a,ha); SET_FLOAT_WORD(b,hb); } } /* medium size a and b */ w = a-b; if (w>b) { SET_FLOAT_WORD(t1,ha&0xfffff000); t2 = a-t1; w = __ieee754_sqrtf(t1*t1-(b*(-b)-t2*(a+t1))); } else { a = a+a; SET_FLOAT_WORD(y1,hb&0xfffff000); y2 = b - y1; SET_FLOAT_WORD(t1,(ha+0x00800000)&0xfffff000); t2 = a - t1; w = __ieee754_sqrtf(t1*y1-(w*(-w)-(t1*y2+t2*b))); } if(k!=0) { SET_FLOAT_WORD(t1,0x3f800000+(k<<23)); return t1*w; } else return w; }
static float gammaf_positive (float x, int *exp2_adj) { int local_signgam; if (x < 0.5f) { *exp2_adj = 0; return __ieee754_expf (__ieee754_lgammaf_r (x + 1, &local_signgam)) / x; } else if (x <= 1.5f) { *exp2_adj = 0; return __ieee754_expf (__ieee754_lgammaf_r (x, &local_signgam)); } else if (x < 2.5f) { *exp2_adj = 0; float x_adj = x - 1; return (__ieee754_expf (__ieee754_lgammaf_r (x_adj, &local_signgam)) * x_adj); } else { float eps = 0; float x_eps = 0; float x_adj = x; float prod = 1; if (x < 4.0f) { /* Adjust into the range for applying Stirling's approximation. */ float n = __ceilf (4.0f - x); x_adj = math_narrow_eval (x + n); x_eps = (x - (x_adj - n)); prod = __gamma_productf (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. */ float exp_adj = -eps; float x_adj_int = __roundf (x_adj); float x_adj_frac = x_adj - x_adj_int; int x_adj_log2; float x_adj_mant = __frexpf (x_adj, &x_adj_log2); if (x_adj_mant < (float) M_SQRT1_2) { x_adj_log2--; x_adj_mant *= 2.0f; } *exp2_adj = x_adj_log2 * (int) x_adj_int; float ret = (__ieee754_powf (x_adj_mant, x_adj) * __ieee754_exp2f (x_adj_log2 * x_adj_frac) * __ieee754_expf (-x_adj) * __ieee754_sqrtf (2 * (float) M_PI / x_adj) / prod); exp_adj += x_eps * __ieee754_logf (x_adj); float bsum = gamma_coeff[NCOEFF - 1]; float 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 * __expm1f (exp_adj); } }