コード例 #1
0
ファイル: nexttoward.c プロジェクト: 4ian/emscripten
double nexttoward(double x, long double y)
{
	union {double f; uint64_t i;} ux = {x};
	int e;

	if (isnan(x) || isnan(y))
		return x + y;
	if (x == y)
		return y;
	if (x == 0) {
		ux.i = 1;
		if (signbit(y))
			ux.i |= 1ULL<<63;
	} else if (x < y) {
		if (signbit(x))
			ux.i--;
		else
			ux.i++;
	} else {
		if (signbit(x))
			ux.i++;
		else
			ux.i--;
	}
	e = ux.i>>52 & 0x7ff;
	/* raise overflow if ux.f is infinite and x is finite */
	if (e == 0x7ff)
		FORCE_EVAL(x+x);
	/* raise underflow if ux.f is subnormal or zero */
	if (e == 0)
		FORCE_EVAL(x*x + ux.f*ux.f);
	return ux.f;
}
コード例 #2
0
ファイル: exp.c プロジェクト: petkaantonov/HTML-Music-Player
double exp(double x)
{
	double_t hi, lo, c, xx, y;
	int k, sign;
	uint32_t hx;

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

	/* special cases */
	if (hx >= 0x4086232b) {  /* if |x| >= 708.39... */
		if (isnan(x))
			return x;
		if (x > 709.782712893383973096) {
			/* overflow if x!=inf */
			x *= 0x1p1023;
			return x;
		}
		if (x < -708.39641853226410622) {
			/* underflow if x!=-inf */
			FORCE_EVAL((float)(-0x1p-149/x));
			if (x < -745.13321910194110842)
				return 0;
		}
	}

	/* argument reduction */
	if (hx > 0x3fd62e42) {  /* if |x| > 0.5 ln2 */
		if (hx >= 0x3ff0a2b2)  /* if |x| >= 1.5 ln2 */
			k = (int)(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 > 0x3e300000)  {  /* if |x| > 2**-28 */
		k = 0;
		hi = x;
		lo = 0;
	} else {
		/* inexact if x!=0 */
		FORCE_EVAL(0x1p1023 + x);
		return 1 + x;
	}

	/* x is now in primary range */
	xx = x*x;
	c = x - xx*(__EXP_P1+xx*(__EXP_P2+xx*(__EXP_P3+xx*(__EXP_P4+xx*__EXP_P5))));
	y = 1 + (x*c/(2-c) - lo + hi);
	if (k == 0)
		return y;
	return scalbn(y, k);
}
コード例 #3
0
ファイル: expf.c プロジェクト: IngenicC/xboot
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);
}
コード例 #4
0
ファイル: tanl.c プロジェクト: RafaelRMachado/musl
long double tanl(long double x)
{
	union IEEEl2bits z;
	long double y[2];
	unsigned n;

	z.e = x;
	z.bits.sign = 0;

	/* If x = NaN or Inf, then tan(x) = NaN. */
	if (z.bits.exp == 0x7fff)
		return (x - x) / (x - x);

	/* |x| < (double)pi/4 */
	if (z.e < M_PI_4) {
		/* |x| < 0x1p-64 */
		if (z.bits.exp < 0x3fff - 64) {
			/* raise inexact if x!=0 and underflow if subnormal */
			FORCE_EVAL(z.bits.exp == 0 ? x/0x1p120f : x+0x1p120f);
			return x;
		}
		return __tanl(x, 0, 0);
	}

	n = __rem_pio2l(x, y);
	return __tanl(y[0], y[1], n&1);
}
コード例 #5
0
ファイル: asinhf.c プロジェクト: saltstar/smartnix
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
float asinhf(float x) {
    union {
        float f;
        uint32_t i;
    } u = {.f = x};
    uint32_t i = u.i & 0x7fffffff;
    unsigned s = u.i >> 31;

    /* |x| */
    u.i = i;
    x = u.f;

    if (i >= 0x3f800000 + (12 << 23)) {
        /* |x| >= 0x1p12 or inf or nan */
        x = logf(x) + 0.693147180559945309417232121458176568f;
    } else if (i >= 0x3f800000 + (1 << 23)) {
        /* |x| >= 2 */
        x = logf(2 * x + 1 / (sqrtf(x * x + 1) + x));
    } else if (i >= 0x3f800000 - (12 << 23)) {
        /* |x| >= 0x1p-12, up to 1.6ulp error in [0.125,0.5] */
        x = log1pf(x + x * x / (sqrtf(x * x + 1) + 1));
    } else {
        /* |x| < 0x1p-12, raise inexact if x!=0 */
        FORCE_EVAL(x + 0x1p120f);
    }
    return s ? -x : x;
}
コード例 #6
0
ファイル: coshl.c プロジェクト: 4ian/emscripten
long double coshl(long double x)
{
	union ldshape u = {x};
	unsigned ex = u.i.se & 0x7fff;
	uint32_t w;
	long double t;

	/* |x| */
	u.i.se = ex;
	x = u.f;
	w = u.i.m >> 32;

	/* |x| < log(2) */
	if (ex < 0x3fff-1 || (ex == 0x3fff-1 && w < 0xb17217f7)) {
		if (ex < 0x3fff-32) {
			FORCE_EVAL(x + 0x1p120f);
			return 1;
		}
		t = expm1l(x);
		return 1 + t*t/(2*(1+t));
	}

	/* |x| < log(LDBL_MAX) */
	if (ex < 0x3fff+13 || (ex == 0x3fff+13 && w < 0xb17217f7)) {
		t = expl(x);
		return 0.5*(t + 1/t);
	}

	/* |x| > log(LDBL_MAX) or nan */
	t = expl(0.5*x);
	return 0.5*t*t;
}
コード例 #7
0
ファイル: nexttoward.c プロジェクト: KGG814/AOS
double nexttoward(double x, long double y)
{
	union dshape ux;
	int e;

	if (isnan(x) || isnan(y))
		return x + y;
	if (x == y)
		return y;
	ux.value = x;
	if (x == 0) {
		ux.bits = 1;
		if (signbit(y))
			ux.bits |= SIGN;
	} else if (x < y) {
		if (signbit(x))
			ux.bits--;
		else
			ux.bits++;
	} else {
		if (signbit(x))
			ux.bits++;
		else
			ux.bits--;
	}
	e = ux.bits>>52 & 0x7ff;
	/* raise overflow if ux.value is infinite and x is finite */
	if (e == 0x7ff)
		return x + x;
	/* raise underflow if ux.value is subnormal or zero */
	if (e == 0)
		FORCE_EVAL(x*x + ux.value*ux.value);
	return ux.value;
}
コード例 #8
0
ファイル: coshf.c プロジェクト: 4ian/emscripten
float coshf(float x)
{
	union {float f; uint32_t i;} u = {.f = x};
	uint32_t w;
	float t;

	/* |x| */
	u.i &= 0x7fffffff;
	x = u.f;
	w = u.i;

	/* |x| < log(2) */
	if (w < 0x3f317217) {
		if (w < 0x3f800000 - (12<<23)) {
			FORCE_EVAL(x + 0x1p120f);
			return 1;
		}
		t = expm1f(x);
		return 1 + t*t/(2*(1+t));
	}

	/* |x| < log(FLT_MAX) */
	if (w < 0x42b17217) {
		t = expf(x);
		return 0.5f*(t + 1/t);
	}

	/* |x| > log(FLT_MAX) or nan */
	t = __expo2f(x);
	return t;
}
コード例 #9
0
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
long double asinhl(long double x)
{
	union ldshape u = {x};
	unsigned e = u.i.se & 0x7fff;
	unsigned s = u.i.se >> 15;

	/* |x| */
	u.i.se = e;
	x = u.f;

	if (e >= 0x3fff + 32) {
		/* |x| >= 0x1p32 or inf or nan */
		x = logl(x) + 0.693147180559945309417232121458176568L;
	} else if (e >= 0x3fff + 1) {
		/* |x| >= 2 */
		x = logl(2*x + 1/(sqrtl(x*x+1)+x));
	} else if (e >= 0x3fff - 32) {
		/* |x| >= 0x1p-32 */
		x = log1pl(x + x*x/(sqrtl(x*x+1)+1));
	} else {
		/* |x| < 0x1p-32, raise inexact if x!=0 */
		FORCE_EVAL(x + 0x1p120f);
	}
	return s ? -x : x;
}
コード例 #10
0
ファイル: tan.c プロジェクト: freiling/mojo
double tan(double x) {
  double y[2];
  uint32_t ix;
  unsigned n;

  GET_HIGH_WORD(ix, x);
  ix &= 0x7fffffff;

  /* |x| ~< pi/4 */
  if (ix <= 0x3fe921fb) {
    if (ix < 0x3e400000) { /* |x| < 2**-27 */
      /* raise inexact if x!=0 and underflow if subnormal */
      FORCE_EVAL(ix < 0x00100000 ? x / 0x1p120f : x + 0x1p120f);
      return x;
    }
    return __tan(x, 0.0, 0);
  }

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

  /* argument reduction */
  n = __rem_pio2(x, y);
  return __tan(y[0], y[1], n & 1);
}
コード例 #11
0
ファイル: sin.c プロジェクト: dubhater/zimg
double _mysin(double x)
{
	double y[2];
	uint32_t ix;
	unsigned n;

	/* High word of x. */
	GET_HIGH_WORD(ix, x);
	ix &= 0x7fffffff;

	/* |x| ~< pi/4 */
	if (ix <= 0x3fe921fb) {
		if (ix < 0x3e500000) {  /* |x| < 2**-26 */
			/* raise inexact if x != 0 and underflow if subnormal*/
			FORCE_EVAL(ix < 0x00100000 ? x/get_0x1p120f() : x+get_0x1p120f());
			return x;
		}
		return my__sin(x, 0.0, 0);
	}

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

	/* argument reduction needed */
	n = my__rem_pio2(x, y);
	switch (n&3) {
	case 0: return  my__sin(y[0], y[1], 1);
	case 1: return  my__cos(y[0], y[1]);
	case 2: return -my__sin(y[0], y[1], 1);
	default:
		return -my__cos(y[0], y[1]);
	}
}
コード例 #12
0
ファイル: sinl.c プロジェクト: 4ian/emscripten
long double sinl(long double x)
{
	union ldshape u = {x};
	unsigned n;
	long double y[2], hi, lo;

	u.i.se &= 0x7fff;
	if (u.i.se == 0x7fff)
		return x - x;
	if (u.f < M_PI_4) {
		if (u.i.se < 0x3fff - LDBL_MANT_DIG/2) {
			/* raise inexact if x!=0 and underflow if subnormal */
			FORCE_EVAL(u.i.se == 0 ? x*0x1p-120f : x+0x1p120f);
			return x;
		}
		return __sinl(x, 0.0, 0);
	}
	n = __rem_pio2l(x, y);
	hi = y[0];
	lo = y[1];
	switch (n & 3) {
	case 0:
		return __sinl(hi, lo, 1);
	case 1:
		return __cosl(hi, lo);
	case 2:
		return -__sinl(hi, lo, 1);
	case 3:
	default:
		return -__cosl(hi, lo);
	}
}
コード例 #13
0
ファイル: atanh.c プロジェクト: bhuztez/barelibc
/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
double atanh(double x)
{
	union {double f; uint64_t i;} u = {.f = x};
	unsigned e = u.i >> 52 & 0x7ff;
	unsigned s = u.i >> 63;
	double_t y;

	/* |x| */
	u.i &= (uint64_t)-1/2;
	y = u.f;

	if (e < 0x3ff - 1) {
		if (e < 0x3ff - 32) {
			/* handle underflow */
			if (e == 0)
				FORCE_EVAL((float)y);
		} else {
			/* |x| < 0.5, up to 1.7ulp error */
			y = 0.5*log1p(2*y + 2*y*y/(1-y));
		}
	} else {
		/* avoid overflow */
		y = 0.5*log1p(2*(y/(1-y)));
	}
	return s ? -y : y;
}
コード例 #14
0
ファイル: atanhf.c プロジェクト: xboot/xboot
/* atanh(x) = log((1+x)/(1-x))/2 = log1p(2x/(1-x))/2 ~= x + x^3/3 + o(x^5) */
float atanhf(float x)
{
	union {float f; uint32_t i;} u = {.f = x};
	unsigned s = u.i >> 31;
	float_t y;

	/* |x| */
	u.i &= 0x7fffffff;
	y = u.f;

	if (u.i < 0x3f800000 - (1<<23)) {
		if (u.i < 0x3f800000 - (32<<23)) {
			/* handle underflow */
			if (u.i < (1<<23))
				FORCE_EVAL((float)(y*y));
		} else {
			/* |x| < 0.5, up to 1.7ulp error */
			y = 0.5f*log1pf(2*y + 2*y*y/(1-y));
		}
	} else {
		/* avoid overflow */
		y = 0.5f*log1pf(2*(y/(1-y)));
	}
	return s ? -y : y;
}
コード例 #15
0
ファイル: nextafterl.c プロジェクト: bhuztez/barelibc
long double nextafterl(long double x, long double y)
{
	union ldshape ux, uy;

	if (isnan(x) || isnan(y))
		return x + y;
	if (x == y)
		return y;
	ux.f = x;
	if (x == 0) {
		uy.f = y;
		ux.i.m = 1;
		ux.i.se = uy.i.se & 0x8000;
	} else if ((x < y) == !(ux.i.se & 0x8000)) {
		ux.i.m++;
		if (ux.i.m << 1 == 0) {
			ux.i.m = 1ULL << 63;
			ux.i.se++;
		}
	} else {
		if (ux.i.m << 1 == 0) {
			ux.i.se--;
			if (ux.i.se)
				ux.i.m = 0;
		}
		ux.i.m--;
	}
	/* raise overflow if ux is infinite and x is finite */
	if ((ux.i.se & 0x7fff) == 0x7fff)
		return x + x;
	/* raise underflow if ux is subnormal or zero */
	if ((ux.i.se & 0x7fff) == 0)
		FORCE_EVAL(x*x + ux.f*ux.f);
	return ux.f;
}
コード例 #16
0
ファイル: asinh.c プロジェクト: 4ian/emscripten
/* asinh(x) = sign(x)*log(|x|+sqrt(x*x+1)) ~= x - x^3/6 + o(x^5) */
double asinh(double x)
{
	union {double f; uint64_t i;} u = {.f = x};
	unsigned e = u.i >> 52 & 0x7ff;
	unsigned s = u.i >> 63;

	/* |x| */
	u.i &= (uint64_t)-1/2;
	x = u.f;

	if (e >= 0x3ff + 26) {
		/* |x| >= 0x1p26 or inf or nan */
		x = log(x) + 0.693147180559945309417232121458176568;
	} else if (e >= 0x3ff + 1) {
		/* |x| >= 2 */
		x = log(2*x + 1/(sqrt(x*x+1)+x));
	} else if (e >= 0x3ff - 26) {
		/* |x| >= 0x1p-26, up to 1.6ulp error in [0.125,0.5] */
		x = log1p(x + x*x/(sqrt(x*x+1)+1));
	} else {
		/* |x| < 0x1p-26, raise inexact if x != 0 */
		FORCE_EVAL(x + 0x1p120f);
	}
	return s ? -x : x;
}
コード例 #17
0
ファイル: atanl.c プロジェクト: bminor/musl
long double atanl(long double x)
{
	union ldshape u = {x};
	long double w, s1, s2, z;
	int id;
	unsigned e = u.i.se & 0x7fff;
	unsigned sign = u.i.se >> 15;
	unsigned expman;

	if (e >= 0x3fff + LDBL_MANT_DIG + 1) { /* if |x| is large, atan(x)~=pi/2 */
		if (isnan(x))
			return x;
		return sign ? -atanhi[3] : atanhi[3];
	}
	/* Extract the exponent and the first few bits of the mantissa. */
	expman = EXPMAN(u);
	if (expman < ((0x3fff - 2) << 8) + 0xc0) {  /* |x| < 0.4375 */
		if (e < 0x3fff - (LDBL_MANT_DIG+1)/2) {   /* if |x| is small, atanl(x)~=x */
			/* raise underflow if subnormal */
			if (e == 0)
				FORCE_EVAL((float)x);
			return x;
		}
		id = -1;
	} else {
		x = fabsl(x);
		if (expman < (0x3fff << 8) + 0x30) {  /* |x| < 1.1875 */
			if (expman < ((0x3fff - 1) << 8) + 0x60) { /*  7/16 <= |x| < 11/16 */
				id = 0;
				x = (2.0*x-1.0)/(2.0+x);
			} else {                                 /* 11/16 <= |x| < 19/16 */
				id = 1;
				x = (x-1.0)/(x+1.0);
			}
		} else {
			if (expman < ((0x3fff + 1) << 8) + 0x38) { /* |x| < 2.4375 */
				id = 2;
				x = (x-1.5)/(1.0+1.5*x);
			} else {                                 /* 2.4375 <= |x| */
				id = 3;
				x = -1.0/x;
			}
		}
	}
	/* end of argument reduction */
	z = x*x;
	w = z*z;
	/* break sum aT[i]z**(i+1) into odd and even poly */
	s1 = z*T_even(w);
	s2 = w*T_odd(w);
	if (id < 0)
		return x - x*(s1+s2);
	z = atanhi[id] - ((x*(s1+s2) - atanlo[id]) - x);
	return sign ? -z : z;
}
コード例 #18
0
ファイル: cosf.c プロジェクト: freiling/mojo
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);
  }
}
コード例 #19
0
void sincos(double x, double *sin, double *cos)
{
	double y[2], s, c;
	uint32_t ix;
	unsigned n;

	GET_HIGH_WORD(ix, x);
	ix &= 0x7fffffff;

	/* |x| ~< pi/4 */
	if (ix <= 0x3fe921fb) {
		/* if |x| < 2**-27 * sqrt(2) */
		if (ix < 0x3e46a09e) {
			/* raise inexact if x!=0 and underflow if subnormal */
			FORCE_EVAL(ix < 0x00100000 ? x/0x1p120f : x+0x1p120f);
			*sin = x;
			*cos = 1.0;
			return;
		}
		*sin = __sin(x, 0.0, 0);
		*cos = __cos(x, 0.0);
		return;
	}

	/* sincos(Inf or NaN) is NaN */
	if (ix >= 0x7ff00000) {
		*sin = *cos = x - x;
		return;
	}

	/* argument reduction needed */
	n = __rem_pio2(x, y);
	s = __sin(y[0], y[1], 1);
	c = __cos(y[0], y[1]);
	switch (n&3) {
	case 0:
		*sin = s;
		*cos = c;
		break;
	case 1:
		*sin = c;
		*cos = -s;
		break;
	case 2:
		*sin = -s;
		*cos = -c;
		break;
	case 3:
	default:
		*sin = -c;
		*cos = s;
		break;
	}
}
コード例 #20
0
ファイル: sincosl.c プロジェクト: RafaelRMachado/musl
void sincosl(long double x, long double *sin, long double *cos)
{
	union IEEEl2bits u;
	unsigned n;
	long double y[2], s, c;

	u.e = x;
	u.bits.sign = 0;

	/* x = nan or inf */
	if (u.bits.exp == 0x7fff) {
		*sin = *cos = x - x;
		return;
	}

	/* |x| < (double)pi/4 */
	if (u.e < M_PI_4) {
		/* |x| < 0x1p-64 */
		if (u.bits.exp < 0x3fff - 64) {
			/* raise underflow if subnormal */
			if (u.bits.exp == 0) FORCE_EVAL(x*0x1p-120f);
			*sin = x;
			/* raise inexact if x!=0 */
			*cos = 1.0 + x;
			return;
		}
		*sin = __sinl(x, 0, 0);
		*cos = __cosl(x, 0);
		return;
	}

	n = __rem_pio2l(x, y);
	s = __sinl(y[0], y[1], 1);
	c = __cosl(y[0], y[1]);
	switch (n & 3) {
	case 0:
		*sin = s;
		*cos = c;
		break;
	case 1:
		*sin = c;
		*cos = -s;
		break;
	case 2:
		*sin = -s;
		*cos = -c;
		break;
	case 3:
	default:
		*sin = -c;
		*cos = s;
		break;
	}
}
コード例 #21
0
ファイル: atan.c プロジェクト: xboot/xboot
double atan(double x)
{
	double_t w,s1,s2,z;
	uint32_t ix,sign;
	int id;

	GET_HIGH_WORD(ix, x);
	sign = ix >> 31;
	ix &= 0x7fffffff;
	if (ix >= 0x44100000) {   /* if |x| >= 2^66 */
		if (isnan(x))
			return x;
		z = atanhi[3] + 0x1p-120f;
		return sign ? -z : z;
	}
	if (ix < 0x3fdc0000) {    /* |x| < 0.4375 */
		if (ix < 0x3e400000) {  /* |x| < 2^-27 */
			if (ix < 0x00100000)
				/* raise underflow for subnormal x */
				FORCE_EVAL((float)x);
			return x;
		}
		id = -1;
	} else {
		x = fabs(x);
		if (ix < 0x3ff30000) {  /* |x| < 1.1875 */
			if (ix < 0x3fe60000) {  /*  7/16 <= |x| < 11/16 */
				id = 0;
				x = (2.0*x-1.0)/(2.0+x);
			} else {                /* 11/16 <= |x| < 19/16 */
				id = 1;
				x = (x-1.0)/(x+1.0);
			}
		} else {
			if (ix < 0x40038000) {  /* |x| < 2.4375 */
				id = 2;
				x = (x-1.5)/(1.0+1.5*x);
			} else {                /* 2.4375 <= |x| < 2^66 */
				id = 3;
				x = -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);
	z = atanhi[id] - (x*(s1+s2) - atanlo[id] - x);
	return sign ? -z : z;
}
コード例 #22
0
ファイル: atanf.c プロジェクト: xboot/xboot
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;
}
コード例 #23
0
ファイル: ilogb.c プロジェクト: 5kg/osv
int ilogb(double x)
{
	union dshape u = {x};
	int e = u.bits>>52 & 0x7ff;

	if (!e) {
		u.bits <<= 12;
		if (u.bits == 0) {
			FORCE_EVAL(0/0.0f);
			return FP_ILOGB0;
		}
		/* subnormal x */
		for (e = -0x3ff; u.bits < (uint64_t)1<<63; e--, u.bits<<=1);
		return e;
	}
	if (e == 0x7ff) {
		FORCE_EVAL(0/0.0f);
		return u.bits<<12 ? FP_ILOGBNAN : INT_MAX;
	}
	return e - 0x3ff;
}
コード例 #24
0
ファイル: ilogbl.c プロジェクト: saltstar/smartnix
int ilogbl(long double x) {
    PRAGMA_STDC_FENV_ACCESS_ON
    union ldshape u = {x};
    int e = u.i.se & 0x7fff;

    if (!e) {
        if (x == 0) {
            FORCE_EVAL(0 / 0.0f);
            return FP_ILOGB0;
        }
        /* subnormal x */
        x *= 0x1p120;
        return ilogbl(x) - 120;
    }
    if (e == 0x7fff) {
        FORCE_EVAL(0 / 0.0f);
        u.i.se = 0;
        return u.f ? FP_ILOGBNAN : INT_MAX;
    }
    return e - 0x3fff;
}
コード例 #25
0
ファイル: ilogbl.c プロジェクト: saltstar/smartnix
int ilogbl(long double x) {
    PRAGMA_STDC_FENV_ACCESS_ON
    union ldshape u = {x};
    uint64_t m = u.i.m;
    int e = u.i.se & 0x7fff;

    if (!e) {
        if (m == 0) {
            FORCE_EVAL(0 / 0.0f);
            return FP_ILOGB0;
        }
        /* subnormal x */
        for (e = -0x3fff + 1; m >> 63 == 0; e--, m <<= 1)
            ;
        return e;
    }
    if (e == 0x7fff) {
        FORCE_EVAL(0 / 0.0f);
        return m << 1 ? FP_ILOGBNAN : INT_MAX;
    }
    return e - 0x3fff;
}
コード例 #26
0
ファイル: sinf.c プロジェクト: IngenicC/xboot
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);
	}
}
コード例 #27
0
ファイル: tanl.c プロジェクト: saltstar/smartnix
long double tanl(long double x) {
    union ldshape u = {x};
    long double y[2];
    unsigned n;

    u.i.se &= 0x7fff;
    if (u.i.se == 0x7fff)
        return x - x;
    if (u.f < M_PI_4) {
        if (u.i.se < 0x3fff - LDBL_MANT_DIG / 2) {
            /* raise inexact if x!=0 and underflow if subnormal */
            FORCE_EVAL(u.i.se == 0 ? x * 0x1p-120f : x + 0x1p120f);
            return x;
        }
        return __tanl(x, 0, 0);
    }
    n = __rem_pio2l(x, y);
    return __tanl(y[0], y[1], n & 1);
}
コード例 #28
0
ファイル: ilogb.c プロジェクト: willbittner/mojo
int ilogb(double x)
{
    PRAGMA_STDC_FENV_ACCESS_ON
    union {
        double f;
        uint64_t i;
    } u = {x};
    uint64_t i = u.i;
    int e = i>>52 & 0x7ff;

    if (!e) {
        i <<= 12;
        if (i == 0) {
            FORCE_EVAL(0/0.0f);
            return FP_ILOGB0;
        }
        /* subnormal x */
        for (e = -0x3ff; i>>63 == 0; e--, i<<=1);
        return e;
    }
コード例 #29
0
ファイル: tanh.c プロジェクト: saltstar/smartnix
/* tanh(x) = (exp(x) - exp(-x))/(exp(x) + exp(-x))
 *         = (exp(2*x) - 1)/(exp(2*x) - 1 + 2)
 *         = (1 - exp(-2*x))/(exp(-2*x) - 1 + 2)
 */
double tanh(double x) {
    union {
        double f;
        uint64_t i;
    } u = {.f = x};
    uint32_t w;
    int sign;
    double_t t;

    /* x = |x| */
    sign = u.i >> 63;
    u.i &= (uint64_t)-1 / 2;
    x = u.f;
    w = u.i >> 32;

    if (w > 0x3fe193ea) {
        /* |x| > log(3)/2 ~= 0.5493 or nan */
        if (w > 0x40340000) {
            /* |x| > 20 or nan */
            /* note: this branch avoids raising overflow */
            t = 1 - 0 / x;
        } else {
            t = expm1(2 * x);
            t = 1 - 2 / (t + 2);
        }
    } else if (w > 0x3fd058ae) {
        /* |x| > log(5/3)/2 ~= 0.2554 */
        t = expm1(2 * x);
        t = t / (t + 2);
    } else if (w >= 0x00100000) {
        /* |x| >= 0x1p-1022, up to 2ulp error in [0.1,0.2554] */
        t = expm1(-2 * x);
        t = -t / (t + 2);
    } else {
        /* |x| is subnormal */
        /* note: the branch above would not raise underflow in [0x1p-1023,0x1p-1022) */
        FORCE_EVAL((float)x);
        t = x;
    }
    return sign ? -t : t;
}
コード例 #30
0
ファイル: exp2f.c プロジェクト: 4ian/emscripten
/*
 * exp2f(x): compute the base 2 exponential of x
 *
 * Accuracy: Peak error < 0.501 ulp; location of peak: -0.030110927.
 *
 * Method: (equally-spaced tables)
 *
 *   Reduce x:
 *     x = k + y, for integer k and |y| <= 1/2.
 *     Thus we have exp2f(x) = 2**k * exp2(y).
 *
 *   Reduce y:
 *     y = i/TBLSIZE + z for integer i near y * TBLSIZE.
 *     Thus we have exp2(y) = exp2(i/TBLSIZE) * exp2(z),
 *     with |z| <= 2**-(TBLSIZE+1).
 *
 *   We compute exp2(i/TBLSIZE) via table lookup and exp2(z) via a
 *   degree-4 minimax polynomial with maximum error under 1.4 * 2**-33.
 *   Using double precision for everything except the reduction makes
 *   roundoff error insignificant and simplifies the scaling step.
 *
 *   This method is due to Tang, but I do not use his suggested parameters:
 *
 *      Tang, P.  Table-driven Implementation of the Exponential Function
 *      in IEEE Floating-Point Arithmetic.  TOMS 15(2), 144-157 (1989).
 */
float exp2f(float x)
{
	double_t t, r, z;
	union {float f; uint32_t i;} u = {x};
	union {double f; uint64_t i;} uk;
	uint32_t ix, i0, k;

	/* Filter out exceptional cases. */
	ix = u.i & 0x7fffffff;
	if (ix > 0x42fc0000) {  /* |x| > 126 */
		if (u.i >= 0x43000000 && u.i < 0x80000000) {  /* x >= 128 */
			x *= 0x1p127f;
			return x;
		}
		if (u.i >= 0x80000000) {  /* x < -126 */
			if (u.i >= 0xc3160000 || (u.i & 0x0000ffff))
				FORCE_EVAL(-0x1p-149f/x);
			if (u.i >= 0xc3160000)  /* x <= -150 */
				return 0;
		}
	} else if (ix <= 0x33000000) {  /* |x| <= 0x1p-25 */
		return 1.0f + x;
	}

	/* Reduce x, computing z, i0, and k. */
	u.f = x + redux;
	i0 = u.i;
	i0 += TBLSIZE / 2;
	k = i0 / TBLSIZE;
	uk.i = (uint64_t)(0x3ff + k)<<52;
	i0 &= TBLSIZE - 1;
	u.f -= redux;
	z = x - u.f;
	/* Compute r = exp2(y) = exp2ft[i0] * p(z). */
	r = exp2ft[i0];
	t = r * z;
	r = r + t * (P1 + z * P2) + t * (z * z) * (P3 + z * P4);

	/* Scale by 2**k */
	return r * uk.f;
}