Beispiel #1
0
float
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 = 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 = 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);
	}
}
Beispiel #2
0
float
frexpf(float x, int *eptr)
{
	int32_t hx,ix;
	GET_FLOAT_WORD(hx,x);
	ix = 0x7fffffff&hx;
	*eptr = 0;
	if(ix>=0x7f800000||(ix==0)) return x;	/* 0,inf,nan */
	if (ix<0x00800000) {		/* subnormal */
	    x *= two25;
	    GET_FLOAT_WORD(hx,x);
	    ix = hx&0x7fffffff;
	    *eptr = -25;
	}
	*eptr += (ix>>23)-126;
	hx = (hx&0x807fffff)|0x3f000000;
	*(int*)(void*)&x = hx;
	return x;
}
Beispiel #3
0
float __erff(float x)
{
	int32_t hx,ix,i;
	float R,S,P,Q,s,y,z,r;
	GET_FLOAT_WORD(hx,x);
	ix = hx&0x7fffffff;
	if(ix>=0x7f800000) {		/* erf(nan)=nan */
	    i = ((u_int32_t)hx>>31)<<1;
	    return (float)(1-i)+one/x;	/* erf(+-inf)=+-1 */
	}
Beispiel #4
0
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  */
	if(ix>=0x7f800000) return  one/(x+x*x);
        if(ix==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 = sinf(x);
                c = cosf(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<0x7f000000) {  /* make sure x+x not overflow */
                    z = -cosf(x+x);
                    if ((s*c)<zero) cc = z/ss;
                    else            ss = z/cc;
                }
#ifdef DEAD_CODE
                if(ix>0x80000000) z = (invsqrtpi*ss)/sqrtf(x);
                else
#endif
		{
                    u = pzerof(x); v = qzerof(x);
                    z = invsqrtpi*(u*ss+v*cc)/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)));
}
Beispiel #5
0
float cosf(float x) {
  double y;
  uint32_t ix;
  unsigned n, sign;

  GET_FLOAT_WORD(ix, x);
  sign = ix >> 31;
  ix &= 0x7fffffff;

  if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
    if (ix < 0x39800000) { /* |x| < 2**-12 */
      /* raise inexact if x != 0 */
      FORCE_EVAL(x + 0x1p120f);
      return 1.0f;
    }
    return __cosdf(x);
  }
  if (ix <= 0x407b53d1) { /* |x| ~<= 5*pi/4 */
    if (ix > 0x4016cbe3)  /* |x|  ~> 3*pi/4 */
      return -__cosdf(sign ? x + c2pio2 : x - c2pio2);
    else {
      if (sign)
        return __sindf(x + c1pio2);
      else
        return __sindf(c1pio2 - x);
    }
  }
  if (ix <= 0x40e231d5) { /* |x| ~<= 9*pi/4 */
    if (ix > 0x40afeddf)  /* |x| ~> 7*pi/4 */
      return __cosdf(sign ? x + c4pio2 : x - c4pio2);
    else {
      if (sign)
        return __sindf(-x - c3pio2);
      else
        return __sindf(x - c3pio2);
    }
  }

  /* cos(Inf or NaN) is NaN */
  if (ix >= 0x7f800000)
    return x - x;

  /* general argument reduction needed */
  n = __rem_pio2f(x, &y);
  switch (n & 3) {
    case 0:
      return __cosdf(y);
    case 1:
      return __sindf(-y);
    case 2:
      return -__cosdf(y);
    default:
      return __sindf(y);
  }
}
Beispiel #6
0
float remainderf(float x, float p)
{
	int32_t hx,hp;
	uint32_t sx;
	float p_half;

	GET_FLOAT_WORD(hx, x);
	GET_FLOAT_WORD(hp, p);
	sx = hx & 0x80000000;
	hp &= 0x7fffffff;
	hx &= 0x7fffffff;

	/* purge off exception values */
	if (hp == 0 || hx >= 0x7f800000 || hp > 0x7f800000)  /* p = 0, x not finite, p is NaN */
		return (x*p)/(x*p);

	if (hp <= 0x7effffff)
		x = fmodf(x, p + p);  /* now x < 2p */
	if (hx - hp == 0)
		return 0.0f*x;
	x = fabsf(x);
	p = fabsf(p);
	if (hp < 0x01000000) {
		if (x + x > p) {
			x -= p;
			if (x + x >= p)
				x -= p;
		}
	} else {
		p_half = 0.5f*p;
		if (x > p_half) {
			x -= p;
			if (x >= p_half)
				x -= p;
		}
	}
	GET_FLOAT_WORD(hx, x);
	if ((hx & 0x7fffffff) == 0)
		hx = 0;
	SET_FLOAT_WORD(x, hx ^ sx);
	return x;
}
/*
 * On the SPU, single precision floating point returns only FP_NORMAL and
 * FP_ZERO, since FP_NAN, FP_INFINITE, and FP_SUBNORMAL are not
 * supported, base on the common f_fpclassify.c.
 */
int
__fpclassifyf (float x)
{
  __uint32_t w;

  GET_FLOAT_WORD(w,x);

  if (w == 0x00000000 || w == 0x80000000)
    return FP_ZERO;
  return FP_NORMAL;
}
Beispiel #8
0
float atanf(float x)
{
	float_t w,s1,s2,z;
	uint32_t ix,sign;
	int id;

	GET_FLOAT_WORD(ix, x);
	sign = ix>>31;
	ix &= 0x7fffffff;
	if (ix >= 0x4c800000) {  /* if |x| >= 2**26 */
		if (isnan(x))
			return x;
		z = atanhi[3] + 0x1p-120f;
		return sign ? -z : z;
	}
	if (ix < 0x3ee00000) {   /* |x| < 0.4375 */
		if (ix < 0x39800000) {  /* |x| < 2**-12 */
			if (ix < 0x00800000)
				/* raise underflow for subnormal x */
				FORCE_EVAL(x*x);
			return x;
		}
		id = -1;
	} else {
		x = fabsf(x);
		if (ix < 0x3f980000) {  /* |x| < 1.1875 */
			if (ix < 0x3f300000) {  /*  7/16 <= |x| < 11/16 */
				id = 0;
				x = (2.0f*x - 1.0f)/(2.0f + x);
			} else {                /* 11/16 <= |x| < 19/16 */
				id = 1;
				x = (x - 1.0f)/(x + 1.0f);
			}
		} else {
			if (ix < 0x401c0000) {  /* |x| < 2.4375 */
				id = 2;
				x = (x - 1.5f)/(1.0f + 1.5f*x);
			} else {                /* 2.4375 <= |x| < 2**26 */
				id = 3;
				x = -1.0f/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]));
	s2 = w*(aT[1]+w*aT[3]);
	if (id < 0)
		return x - x*(s1+s2);
	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
	return sign ? -z : z;
}
Beispiel #9
0
int isposf(float x)
{
	__int32_t wx;

	GET_FLOAT_WORD(wx, x);

	if (wx & 0x80000000)
		return (0);
	else
		return (1);
}
float nextafterf(float x, float y) {
	int32_t hx, hy, ix, iy;

	GET_FLOAT_WORD(hx, x);
	GET_FLOAT_WORD(hy, y);
	ix = hx & 0x7fffffff;		/* |x| */
	iy = hy & 0x7fffffff;		/* |y| */

	/* x is nan or y is nan? */
	if ((ix > 0x7f800000) || (iy > 0x7f800000))
		return x + y;

	if (x == y)
		return y;

	if (ix == 0) { /* x == 0? */
		SET_FLOAT_WORD(x, (hy & 0x80000000) | 1);
		return x;
	}

	if (hx >= 0) { /* x > 0 */
		if (hx > hy) { /* x > y: x -= ulp */
			hx -= 1;
		} else { /* x < y: x += ulp */
			hx += 1;
		}
	} else { /* x < 0 */
		if (hy >= 0 || hx > hy) { /* x < y: x -= ulp */
			hx -= 1;
		} else { /* x > y: x += ulp */
			hx += 1;
		}
	}
	hy = hx & 0x7f800000;
	if (hy >= 0x7f800000) {
		x = x + x; /* overflow */
		return x; /* overflow */
	}
	SET_FLOAT_WORD(x, hx);
	return x;
}
Beispiel #11
0
float
__ieee754_remainderf(float x, float p)
{
	int32_t hx,hp;
	u_int32_t sx;
	float p_half;

	GET_FLOAT_WORD(hx,x);
	GET_FLOAT_WORD(hp,p);
	sx = hx&0x80000000;
	hp &= 0x7fffffff;
	hx &= 0x7fffffff;

    /* purge off exception values */
	if((hp==0)||			 	/* p = 0 */
	  (hx>=0x7f800000)||			/* x not finite */
	  ((hp>0x7f800000)))			/* p is NaN */
	    return nan_mix_op(x, p, *)/nan_mix_op(x, p, *);


	if (hp<=0x7effffff) x = __ieee754_fmodf(x,p+p);	/* now x < 2p */
	if ((hx-hp)==0) return zero*x;
	x  = fabsf(x);
	p  = fabsf(p);
	if (hp<0x01000000) {
	    if(x+x>p) {
		x-=p;
		if(x+x>=p) x -= p;
	    }
	} else {
	    p_half = (float)0.5*p;
	    if(x>p_half) {
		x-=p;
		if(x>=p_half) x -= p;
	    }
	}
	GET_FLOAT_WORD(hx,x);
	if ((hx&0x7fffffff)==0) hx = 0;
	SET_FLOAT_WORD(x,hx^sx);
	return x;
}
Beispiel #12
0
float atanf(float x)
{
	float w,s1,s2,z;
	int32_t ix,hx,id;

	GET_FLOAT_WORD(hx, x);
	ix = hx & 0x7fffffff;
	if (ix >= 0x4c800000) {  /* if |x| >= 2**26 */
		if (ix > 0x7f800000)  /* NaN */
			return x+x;
		if (hx > 0)
			return  atanhi[3] + *(volatile float *)&atanlo[3];
		else
			return -atanhi[3] - *(volatile float *)&atanlo[3];
	}
	if (ix < 0x3ee00000) {   /* |x| < 0.4375 */
		if (ix < 0x39800000) {  /* |x| < 2**-12 */
			/* raise inexact */
			if(huge+x>1.0f)
				return x;
		}
		id = -1;
	} else {
		x = fabsf(x);
		if (ix < 0x3f980000) {  /* |x| < 1.1875 */
			if (ix < 0x3f300000) {  /*  7/16 <= |x| < 11/16 */
				id = 0;
				x = (2.0f*x - 1.0f)/(2.0f + x);
			} else {                /* 11/16 <= |x| < 19/16 */
				id = 1;
				x = (x - 1.0f)/(x + 1.0f);
			}
		} else {
			if (ix < 0x401c0000) {  /* |x| < 2.4375 */
				id = 2;
				x = (x - 1.5f)/(1.0f + 1.5f*x);
			} else {                /* 2.4375 <= |x| < 2**26 */
				id = 3;
				x = -1.0f/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]));
	s2 = w*(aT[1]+w*aT[3]);
	if (id < 0)
		return x - x*(s1+s2);
	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
	return hx < 0 ? -z : z;
}
Beispiel #13
0
float
cosf(float x)
{
    float y[2];
    int32_t n, hx, ix;

    GET_FLOAT_WORD(hx,x);
    ix = hx & 0x7fffffff;

    if(ix <= 0x3f490fda) {		/* |x| ~<= pi/4 */
        if(ix<0x39800000)		/* |x| < 2**-12 */
            if(((int)x)==0) return 1.0;	/* 1 with inexact if x != 0 */
        return __kernel_cosdf(x);
    }
    if(ix<=0x407b53d1) {		/* |x| ~<= 5*pi/4 */
        if(ix>0x4016cbe3)		/* |x|  ~> 3*pi/4 */
            return -__kernel_cosdf(x + (hx > 0 ? -c2pio2 : c2pio2));
        else {
            if(hx>0)
                return __kernel_sindf(c1pio2 - x);
            else
                return __kernel_sindf(x + c1pio2);
        }
    }
    if(ix<=0x40e231d5) {		/* |x| ~<= 9*pi/4 */
        if(ix>0x40afeddf)		/* |x|  ~> 7*pi/4 */
            return __kernel_cosdf(x + (hx > 0 ? -c4pio2 : c4pio2));
        else {
            if(hx>0)
                return __kernel_sindf(x - c3pio2);
            else
                return __kernel_sindf(-c3pio2 - x);
        }
    }

    /* cos(Inf or NaN) is NaN */
    else if (ix>=0x7f800000) return x-x;

    /* general argument reduction needed */
    else {
        n = __ieee754_rem_pio2f(x,y);
        switch(n&3) {
        case 0:
            return  __kernel_cosdf((double)y[0]+y[1]);
        case 1:
            return  __kernel_sindf(-(double)y[0]-y[1]);
        case 2:
            return -__kernel_cosdf((double)y[0]+y[1]);
        default:
            return  __kernel_sindf((double)y[0]+y[1]);
        }
    }
}
Beispiel #14
0
float 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 1.0f/(x*x);
	x = fabsf(x);
	if (ix >= 0x40000000) {  /* |x| >= 2.0 */
		s = sinf(x);
		c = cosf(x);
		ss = s-c;
		cc = s+c;
		if (ix < 0x7f000000) {  /* make sure x+x does not overflow */
			z = -cosf(x+x);
			if (s*c < 0.0f)
				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 > 0x80000000)
			z = (invsqrtpi*cc)/sqrtf(x);
		else {
			u = pzerof(x);
			v = qzerof(x);
			z = invsqrtpi*(u*cc-v*ss)/sqrtf(x);
		}
		return z;
	}
	if (ix < 0x39000000) {  /* |x| < 2**-13 */
		/* raise inexact if x != 0 */
		if (huge+x > 1.0f) {
			if (ix < 0x32000000)  /* |x| < 2**-27 */
				return 1.0f;
			return 1.0f - 0.25f*x*x;
		}
	}
	z = x*x;
	r =  z*(R02+z*(R03+z*(R04+z*R05)));
	s =  1.0f+z*(S01+z*(S02+z*(S03+z*S04)));
	if(ix < 0x3F800000) {   /* |x| < 1.00 */
		return 1.0f + z*(-0.25f + (r/s));
	} else {
		u = 0.5f*x;
		return (1.0f+u)*(1.0f-u) + z*(r/s);
	}
}
Beispiel #15
0
float
logbf(float x)
{
        int32_t ix;
        GET_FLOAT_WORD(ix,x);
        ix &= 0x7fffffff;                       /* high |x| */
        if(ix==0) return (float)-1.0/fabsf(x);
        if(ix>=0x7f800000) return x*x;
        if((ix>>=23)==0)                        /* IEEE 754 logb */
                return -126.0;
        else
                return (float) (ix-127);
Beispiel #16
0
Datei: j1f.c Projekt: KGG814/AOS
float 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 (ix >= 0x7f800000)
		return 1.0f/(x+x*x);
	if (ix == 0)
		return -1.0f/0.0f;
	if (hx < 0)
		return 0.0f/0.0f;
	if (ix >= 0x40000000) {  /* |x| >= 2.0 */
		s = sinf(x);
		c = cosf(x);
		ss = -s-c;
		cc = s-c;
		if (ix < 0x7f000000) {  /* make sure x+x not overflow */
			z = cosf(x+x);
			if (s*c > 0.0f)
				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)/sqrtf(x);
		else {
			u = ponef(x);
			v = qonef(x);
			z = invsqrtpi*(u*ss+v*cc)/sqrtf(x);
		}
		return z;
	}
	if (ix <= 0x24800000)  /* 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 = 1.0f+z*(V0[0]+z*(V0[1]+z*(V0[2]+z*(V0[3]+z*V0[4]))));
	return x*(u/v) + tpi*(j1f(x)*logf(x)-1.0f/x);
}
Beispiel #17
0
float ynf(int n, float x) {
    uint32_t ix, ib;
    int nm1, sign, i;
    float a, b, temp;

    GET_FLOAT_WORD(ix, x);
    sign = ix >> 31;
    ix &= 0x7fffffff;
    if (ix > 0x7f800000) /* nan */
        return x;
    if (sign && ix != 0) /* x < 0 */
        return 0 / 0.0f;
    if (ix == 0x7f800000)
        return 0.0f;

    if (n == 0)
        return y0f(x);
    if (n < 0) {
        nm1 = -(n + 1);
        sign = n & 1;
    } else {
        nm1 = n - 1;
        sign = 0;
    }
    if (nm1 == 0)
        return sign ? -y1f(x) : y1f(x);

    a = y0f(x);
    b = y1f(x);
    /* quit if b is -inf */
    GET_FLOAT_WORD(ib, b);
    for (i = 0; i < nm1 && ib != 0xff800000;) {
        i++;
        temp = b;
        b = (2.0f * i / x) * b - a;
        GET_FLOAT_WORD(ib, b);
        a = temp;
    }
    return sign ? -b : b;
}
Beispiel #18
0
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;
}
Beispiel #19
0
float
__ieee754_log10f(float x)
{
	float f,hfsq,hi,lo,r,y;
	int32_t i,k,hx;

	GET_FLOAT_WORD(hx,x);

	k=0;
	if (hx < 0x00800000) {			/* x < 2**-126  */
	    if ((hx&0x7fffffff)==0)
		return -two25/vzero;		/* log(+-0)=-inf */
	    if (hx<0) return (x-x)/zero;	/* log(-#) = NaN */
	    k -= 25; x *= two25; /* subnormal number, scale up x */
	    GET_FLOAT_WORD(hx,x);
	}
	if (hx >= 0x7f800000) return x+x;
	if (hx == 0x3f800000)
	    return zero;			/* log(1) = +0 */
	k += (hx>>23)-127;
	hx &= 0x007fffff;
	i = (hx+(0x4afb0d))&0x800000;
	SET_FLOAT_WORD(x,hx|(i^0x3f800000));	/* normalize x or x/2 */
	k += (i>>23);
	y = (float)k;
	f = x - (float)1.0;
	hfsq = (float)0.5*f*f;
	r = k_log1pf(f);

	/* See e_log2f.c and e_log2.c for details. */
	if (sizeof(float_t) > sizeof(float))
		return (r - hfsq + f) * ((float_t)ivln10lo + ivln10hi) +
		    y * ((float_t)log10_2lo + log10_2hi);
	hi = f - hfsq;
	GET_FLOAT_WORD(hx,hi);
	SET_FLOAT_WORD(hi,hx&0xfffff000);
	lo = (f - hi) - hfsq + r;
	return y*log10_2lo + (lo+hi)*ivln10lo + lo*ivln10hi + hi*ivln10hi +
	    y*log10_2hi;
}
Beispiel #20
0
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));
}
Beispiel #21
0
float expf(float x)
{
	float_t hi, lo, c, xx, y;
	int k, sign;
	uint32_t hx;

	GET_FLOAT_WORD(hx, x);
	sign = hx >> 31;   /* sign bit of x */
	hx &= 0x7fffffff;  /* high word of |x| */

	/* special cases */
	if (hx >= 0x42aeac50) {  /* if |x| >= -87.33655f or NaN */
		if (hx >= 0x42b17218 && !sign) {  /* x >= 88.722839f */
			/* overflow */
			x *= 0x1p127f;
			return x;
		}
		if (sign) {
			/* underflow */
			FORCE_EVAL(-0x1p-149f/x);
			if (hx >= 0x42cff1b5)  /* x <= -103.972084f */
				return 0;
		}
	}

	/* argument reduction */
	if (hx > 0x3eb17218) {  /* if |x| > 0.5 ln2 */
		if (hx > 0x3f851592)  /* if |x| > 1.5 ln2 */
			k = invln2*x + half[sign];
		else
			k = 1 - sign - sign;
		hi = x - k*ln2hi;  /* k*ln2hi is exact here */
		lo = k*ln2lo;
		x = hi - lo;
	} else if (hx > 0x39000000) {  /* |x| > 2**-14 */
		k = 0;
		hi = x;
		lo = 0;
	} else {
		/* raise inexact */
		FORCE_EVAL(0x1p127f + x);
		return 1 + x;
	}

	/* x is now in primary range */
	xx = x*x;
	c = x - xx*(P1+xx*P2);
	y = 1 + (x*c/(2-c) - lo + hi);
	if (k == 0)
		return y;
	return scalbnf(y, k);
}
Beispiel #22
0
int isnanf (float x)
{
  __int32_t wx;
  int exp;

  GET_FLOAT_WORD (wx, x);
  exp = (wx & 0x7f800000) >> 23;

  if ((exp == 0x7f8) && (wx & 0x7fffff))
    return (1);
  else
    return (0);
}
Beispiel #23
0
float
sinf(float x)
{
    double y;
    int32_t n, hx, ix;

    GET_FLOAT_WORD(hx,x);
    ix = hx & 0x7fffffff;

    if(ix <= 0x3f490fda) {		/* |x| ~<= pi/4 */
        if(ix<0x39800000)		/* |x| < 2**-12 */
            if(((int)x)==0) return x;	/* x with inexact if x != 0 */
        return __kernel_sindf(x);
    }
    if(ix<=0x407b53d1) {		/* |x| ~<= 5*pi/4 */
        if(ix<=0x4016cbe3) {	/* |x| ~<= 3pi/4 */
            if(hx>0)
                return __kernel_cosdf(x - s1pio2);
            else
                return -__kernel_cosdf(x + s1pio2);
        } else
            return __kernel_sindf((hx > 0 ? s2pio2 : -s2pio2) - x);
    }
    if(ix<=0x40e231d5) {		/* |x| ~<= 9*pi/4 */
        if(ix<=0x40afeddf) {	/* |x| ~<= 7*pi/4 */
            if(hx>0)
                return -__kernel_cosdf(x - s3pio2);
            else
                return __kernel_cosdf(x + s3pio2);
        } else
            return __kernel_sindf(x + (hx > 0 ? -s4pio2 : s4pio2));
    }

    /* sin(Inf or NaN) is NaN */
    else if (ix>=0x7f800000) return x-x;

    /* general argument reduction needed */
    else {
        n = __ieee754_rem_pio2f(x,&y);
        switch(n&3) {
        case 0:
            return  __kernel_sindf(y);
        case 1:
            return  __kernel_cosdf(y);
        case 2:
            return  __kernel_sindf(-y);
        default:
            return -__kernel_cosdf(y);
        }
    }
}
Beispiel #24
0
float sinf(float x)
{
	double y;
	uint32_t ix;
	int n, sign;

	GET_FLOAT_WORD(ix, x);
	sign = ix >> 31;
	ix &= 0x7fffffff;

	if (ix <= 0x3f490fda) {  /* |x| ~<= pi/4 */
		if (ix < 0x39800000) {  /* |x| < 2**-12 */
			/* raise inexact if x!=0 and underflow if subnormal */
			FORCE_EVAL(ix < 0x00800000 ? x/0x1p120f : x+0x1p120f);
			return x;
		}
		return __sindf(x);
	}
	if (ix <= 0x407b53d1) {  /* |x| ~<= 5*pi/4 */
		if (ix <= 0x4016cbe3) {  /* |x| ~<= 3pi/4 */
			if (sign)
				return -__cosdf(x + s1pio2);
			else
				return __cosdf(x - s1pio2);
		}
		return __sindf(sign ? -(x + s2pio2) : -(x - s2pio2));
	}
	if (ix <= 0x40e231d5) {  /* |x| ~<= 9*pi/4 */
		if (ix <= 0x40afeddf) {  /* |x| ~<= 7*pi/4 */
			if (sign)
				return __cosdf(x + s3pio2);
			else
				return -__cosdf(x - s3pio2);
		}
		return __sindf(sign ? x + s4pio2 : x - s4pio2);
	}

	/* sin(Inf or NaN) is NaN */
	if (ix >= 0x7f800000)
		return x - x;

	/* general argument reduction needed */
	n = __rem_pio2f(x, &y);
	switch (n&3) {
	case 0: return  __sindf(y);
	case 1: return  __cosdf(y);
	case 2: return  __sindf(-y);
	default:
		return -__cosdf(y);
	}
}
Beispiel #25
0
float
expm1f(float x)
{
    float y,hi,lo,c,t,e,hxs,hfx,r1,twopk;
    int32_t k,xsb;
    u_int32_t hx;

    GET_FLOAT_WORD(hx,x);
    xsb = hx&0x80000000;		/* sign bit of x */
    hx &= 0x7fffffff;		/* high word of |x| */

    /* filter out huge and non-finite argument */
    if(hx >= 0x4195b844) {			/* if |x|>=27*ln2 */
        if(hx >= 0x42b17218) {		/* if |x|>=88.721... */
            if(hx>0x7f800000)
                return x+x; 	 /* NaN */
            if(hx==0x7f800000)
                return (xsb==0)? x:-1.0;/* exp(+-inf)={inf,-1} */
            if(x > o_threshold) return huge*huge; /* overflow */
        }
        if(xsb!=0) { /* x < -27*ln2, return -1.0 with inexact */
            if(x+tiny<(float)0.0)	/* raise inexact */
                return tiny-one;	/* return -1 */
        }
    }

    /* argument reduction */
    if(hx > 0x3eb17218) {		/* if  |x| > 0.5 ln2 */
        if(hx < 0x3F851592) {	/* and |x| < 1.5 ln2 */
            if(xsb==0)
            {
                hi = x - ln2_hi;
                lo =  ln2_lo;
                k =  1;
            }
            else
            {
                hi = x + ln2_hi;
                lo = -ln2_lo;
                k = -1;
            }
        } else {
            k  = invln2*x+((xsb==0)?(float)0.5:(float)-0.5);
            t  = k;
            hi = x - t*ln2_hi;	/* t*ln2_hi is exact here */
            lo = t*ln2_lo;
        }
        STRICT_ASSIGN(float, x, hi - lo);
        c  = (hi-x)-lo;
    }
    else if(hx < 0x33000000) {  	/* when |x|<2**-25, return x */
Beispiel #26
0
float
__ieee754_powf(float x, float y)
{
	float z,ax,z_h,z_l,p_h,p_l;
	float y1,t1,t2,r,s,t,u,v,w;
	int32_t i,j,k,yisint,n;
	int32_t hx,hy,ix,iy,is;

	GET_FLOAT_WORD(hx,x);
	GET_FLOAT_WORD(hy,y);
	ix = hx&0x7fffffff;  iy = hy&0x7fffffff;

    /* y==zero: x**0 = 1 */
	if(iy==0) return one;

    /* x==+-1 */
	if(x == 1.0) return one;
	if(x == -1.0 && isinf(y)) return one;

    /* +-NaN return x+y */
	if(__builtin_expect(ix > 0x7f800000 ||
			    iy > 0x7f800000, 0))
		return x+y;

    /* determine if y is an odd int when x < 0
     * yisint = 0	... y is not an integer
     * yisint = 1	... y is an odd int
     * yisint = 2	... y is an even int
     */
	yisint  = 0;
	if(hx<0) {
	    if(iy>=0x4b800000) yisint = 2; /* even integer y */
	    else if(iy>=0x3f800000) {
		k = (iy>>23)-0x7f;	   /* exponent */
		j = iy>>(23-k);
		if((j<<(23-k))==iy) yisint = 2-(j&1);
	    }
	}
Beispiel #27
0
float powf(float x, float y)
{
	float z,ax,z_h,z_l,p_h,p_l;
	float y1,t1,t2,r,s,sn,t,u,v,w;
	int32_t i,j,k,yisint,n;
	int32_t hx,hy,ix,iy,is;

	GET_FLOAT_WORD(hx, x);
	GET_FLOAT_WORD(hy, y);
	ix = hx & 0x7fffffff;
	iy = hy & 0x7fffffff;

	/* x**0 = 1, even if x is NaN */
	if (iy == 0)
		return 1.0f;
	/* 1**y = 1, even if y is NaN */
	if (hx == 0x3f800000)
		return 1.0f;
	/* NaN if either arg is NaN */
	if (ix > 0x7f800000 || iy > 0x7f800000)
		return x + y;

	/* determine if y is an odd int when x < 0
	 * yisint = 0       ... y is not an integer
	 * yisint = 1       ... y is an odd int
	 * yisint = 2       ... y is an even int
	 */
	yisint  = 0;
	if (hx < 0) {
		if (iy >= 0x4b800000)
			yisint = 2; /* even integer y */
		else if (iy >= 0x3f800000) {
			k = (iy>>23) - 0x7f;         /* exponent */
			j = iy>>(23-k);
			if ((j<<(23-k)) == iy)
				yisint = 2 - (j & 1);
		}
	}
Beispiel #28
0
/*
 * Return the IEEE remainder and set *quo to the last n bits of the
 * quotient, rounded to the nearest integer.  We choose n=31 because
 * we wind up computing all the integer bits of the quotient anyway as
 * a side-effect of computing the remainder by the shift and subtract
 * method.  In practice, this is far more bits than are needed to use
 * remquo in reduction algorithms.
 */
float
remquof(float x, float y, int *quo)
{
	int32_t n,hx,hy,hz,ix,iy,sx,i;
	u_int32_t q,sxy;

	GET_FLOAT_WORD(hx,x);
	GET_FLOAT_WORD(hy,y);
	sxy = (hx ^ hy) & 0x80000000;
	sx = hx&0x80000000;		/* sign of x */
	hx ^=sx;		/* |x| */
	hy &= 0x7fffffff;	/* |y| */

    /* purge off exception values */
	if(hy==0||hx>=0x7f800000||hy>0x7f800000) /* y=0,NaN;or x not finite */
	    return (x*y)/(x*y);
	if(hx<hy) {
	    q = 0;
	    goto fixup;	/* |x|<|y| return x or x-y */
	} else if(hx==hy) {
	    *quo = 1;
	    return Zero[(u_int32_t)sx>>31];	/* |x|=|y| return x*0*/
	}
Beispiel #29
0
float __hide_kernel_sinf(float x, float y, int iy)
{
	float z,r,v;
	int ix;
	GET_FLOAT_WORD(ix,x);
	ix &= 0x7fffffff;			/* high word of x */
	if(ix<0x32000000)			/* |x| < 2**-27 */
	   {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);
}
Beispiel #30
0
void
SINCOSF_FUNC (float x, float *sinx, float *cosx)
{
  int32_t ix;

  /* High word of x. */
  GET_FLOAT_WORD (ix, x);

  /* |x| ~< pi/4 */
  ix &= 0x7fffffff;
  if (ix <= 0x3f490fd8)
    {
      *sinx = __kernel_sinf (x, 0.0, 0);
      *cosx = __kernel_cosf (x, 0.0);
    }
  else if (ix>=0x7f800000)
    {
      /* sin(Inf or NaN) is NaN */
      *sinx = *cosx = x - x;
      if (ix == 0x7f800000)
	__set_errno (EDOM);
    }
  else
    {
      /* Argument reduction needed.  */
      float y[2];
      int n;

      n = __ieee754_rem_pio2f (x, y);
      switch (n & 3)
	{
	case 0:
	  *sinx = __kernel_sinf (y[0], y[1], 1);
	  *cosx = __kernel_cosf (y[0], y[1]);
	  break;
	case 1:
	  *sinx = __kernel_cosf (y[0], y[1]);
	  *cosx = -__kernel_sinf (y[0], y[1], 1);
	  break;
	case 2:
	  *sinx = -__kernel_sinf (y[0], y[1], 1);
	  *cosx = -__kernel_cosf (y[0], y[1]);
	  break;
	default:
	  *sinx = -__kernel_cosf (y[0], y[1]);
	  *cosx = __kernel_sinf (y[0], y[1], 1);
	  break;
	}
    }
}