Esempio n. 1
0
double
sqrt(double x)
{
	int exponent;
	double val;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (x <= 0) {
		if (x < 0) errno = EDOM;
		return 0;
	}

	if (x > DBL_MAX) return x;	/* for infinity */

	val = frexp(x, &exponent);
	if (exponent & 1) {
		exponent--;
		val *= 2;
	}
	val = ldexp(val + 1.0, exponent/2 - 1);
	/* was: val = (val + 1.0)/2.0; val = ldexp(val, exponent/2); */
	for (exponent = NITER - 1; exponent >= 0; exponent--) {
		val = (val + x / val) / 2.0;
	}
	return val;
}
Esempio n. 2
0
double
atan(double x)
{
	/*      Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/

	static double p[] = {
		-0.13688768894191926929e+2,
		-0.20505855195861651981e+2,
		-0.84946240351320683534e+1,
		-0.83758299368150059274e+0
	};
	static double q[] = {
		 0.41066306682575781263e+2,
		 0.86157349597130242515e+2,
		 0.59578436142597344465e+2,
		 0.15024001160028576121e+2,
		 1.0
	};
	static double a[] = {
		0.0,
		0.52359877559829887307710723554658381,  /* pi/6 */
		M_PI_2,
		1.04719755119659774615421446109316763   /* pi/3 */
	};

	int     neg = x < 0;
	int     n;
	double  g;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (neg) {
		x = -x;
	}
	if (x > 1.0) {
		x = 1.0/x;
		n = 2;
	}
	else    n = 0;

	if (x > 0.26794919243112270647) {       /* 2-sqtr(3) */
		n = n + 1;
		x = (((0.73205080756887729353*x-0.5)-0.5)+x)/
			(1.73205080756887729353+x);
	}

	/* ??? avoid underflow ??? */

	g = x * x;
	x += x * g * POLYNOM3(g, p) / POLYNOM4(g, q);
	if (n > 1) x = -x;
	x += a[n];
	return neg ? -x : x;
}
Esempio n. 3
0
double
exp(double x)
{
	/*	Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/

	static double p[] = {
		0.25000000000000000000e+0,
		0.75753180159422776666e-2,
		0.31555192765684646356e-4
	};

	static double q[] = {
		0.50000000000000000000e+0,
		0.56817302698551221787e-1,
		0.63121894374398503557e-3,
		0.75104028399870046114e-6
	};
	double	xn, g;
	int	n;
	int	negative = x < 0;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (x < M_LN_MIN_D) {
		errno = ERANGE;
		return 0.0;
	}
	if (x > M_LN_MAX_D) {
		errno = ERANGE;
		return HUGE_VAL;
	}

	if (negative) x = -x;
 
	/* ??? avoid underflow ??? */

	n = x * M_LOG2E + 0.5;	/* 1/ln(2) = log2(e), 0.5 added for rounding */
	xn = n;
	{
		double	x1 = (long) x;
		double	x2 = x - x1;

		g = ((x1-xn*0.693359375)+x2) - xn*(-2.1219444005469058277e-4);
	}
	if (negative) {
		g = -g;
		n = -n;
	}
	xn = g * g;
	x = g * POLYNOM2(xn, p);
	n += 1;
	return (ldexp(0.5 + x/(POLYNOM3(xn, q) - x), n));
}
Esempio n. 4
0
static double
asin_acos(double x, int cosfl)
{
	int negative = x < 0;
	int     i;
	double  g;
	static double p[] = {
		-0.27368494524164255994e+2,
		 0.57208227877891731407e+2,
		-0.39688862997540877339e+2,
		 0.10152522233806463645e+2,
		-0.69674573447350646411e+0
	};
	static double q[] = {
		-0.16421096714498560795e+3,
		 0.41714430248260412556e+3,
		-0.38186303361750149284e+3,
		 0.15095270841030604719e+3,
		-0.23823859153670238830e+2,
		 1.0
	};

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}

	if (negative) {
		x = -x;
	}
	if (x > 0.5) {
		i = 1;
		if (x > 1) {
			errno = EDOM;
			return 0;
		}
		g = 0.5 - 0.5 * x;
		x = - sqrt(g);
		x += x;
	}
	else {
		/* ??? avoid underflow ??? */
		i = 0;
		g = x * x;
	}
	x += x * g * POLYNOM4(g, p) / POLYNOM5(g, q);
	if (cosfl) {
		if (! negative) x = -x;
	}
	if ((cosfl == 0) == (i == 1)) {
		x = (x + M_PI_4) + M_PI_4;
	}
	else if (cosfl && negative && i == 1) {
		x = (x + M_PI_2) + M_PI_2;
	}
	if (! cosfl && negative) x = -x;
	return x;
}
Esempio n. 5
0
static double
sinh_cosh(double x, int cosh_flag)
{
	/*	Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/

	static double p[] = {
		-0.35181283430177117881e+6,
		-0.11563521196851768270e+5,
		-0.16375798202630751372e+3,
		-0.78966127417357099479e+0
	};
	static double q[] = {
		-0.21108770058106271242e+7,
		 0.36162723109421836460e+5,
		-0.27773523119650701167e+3,
		 1.0
	};
	int	negative = x < 0;
	double	y = negative ? -x : x;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (! cosh_flag && y <= 1.0) {
		/* ??? check for underflow ??? */
		y = y * y;
		return x + x * y * POLYNOM3(y, p)/POLYNOM3(y,q);
	}

	if (y >= M_LN_MAX_D) {
		/* exp(y) would cause overflow */
#define LNV	0.69316101074218750000e+0
#define VD2M1	0.52820835025874852469e-4
		double	w = y - LNV;
		
		if (w < M_LN_MAX_D+M_LN2-LNV) {
			x = exp(w);
			x += VD2M1 * x;
		}
		else {
			errno = ERANGE;
			x = HUGE_VAL;
		}
	}
	else {
		double	z = exp(y);
		
		x = 0.5 * (z + (cosh_flag ? 1.0 : -1.0)/z);
	}
	return negative ? -x : x;
}
Esempio n. 6
0
double
log(double x)
{
	/*	Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/
	static double a[] = {
		-0.64124943423745581147e2,
		 0.16383943563021534222e2,
		-0.78956112887491257267e0
	};
	static double b[] = {
		-0.76949932108494879777e3,
		 0.31203222091924532844e3,
		-0.35667977739034646171e2,
		 1.0
	};

	double	znum, zden, z, w;
	int	exponent;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (x < 0) {
		errno = EDOM;
		return -HUGE_VAL;
	}
	else if (x == 0) {
		errno = ERANGE;
		return -HUGE_VAL;
	}

	if (x <= DBL_MAX) {
	}
	else return x;	/* for infinity and Nan */
	x = frexp(x, &exponent);
	if (x > M_1_SQRT2) {
		znum = (x - 0.5) - 0.5;
		zden = x * 0.5 + 0.5;
	}
	else {
		znum = x - 0.5;
		zden = znum * 0.5 + 0.5;
		exponent--;
	}
	z = znum/zden; w = z * z;
	x = z + z * w * (POLYNOM2(w,a)/POLYNOM3(w,b));
	z = exponent;
	x += z * (-2.121944400546905827679e-4);
	return x + z * 0.693359375;
}
Esempio n. 7
0
double
ldexp(double fl, int exp)
{
	int sign = 1;
	int currexp;

	if (__IsNan(fl)) {
		errno = EDOM;
		return fl;
	}
	if (fl == 0.0) return 0.0;
	if (fl<0) {
		fl = -fl;
		sign = -1;
	}
	if (fl > DBL_MAX) {		/* for infinity */
		errno = ERANGE;
		return sign * fl;
	}
	fl = frexp(fl,&currexp);
	exp += currexp;
	if (exp > 0) {
		if (exp > DBL_MAX_EXP) {
			errno = ERANGE;
			return sign * HUGE_VAL;
		}
		while (exp>30) {
			fl *= (double) (1L << 30);
			exp -= 30;
		}
		fl *= (double) (1L << exp);
	}
	else	{
		/* number need not be normalized */
		if (exp < DBL_MIN_EXP - DBL_MANT_DIG) {
			return 0.0;
		}
		while (exp<-30) {
			fl /= (double) (1L << 30);
			exp += 30;
		}
		fl /= (double) (1L << -exp);
	}
	return sign * fl;
}
Esempio n. 8
0
double
tanh(double x)
{
	/*	Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/

	static double p[] = {
		-0.16134119023996228053e+4,
		-0.99225929672236083313e+2,
		-0.96437492777225469787e+0
	};
	static double q[] = {
		 0.48402357071988688686e+4,
		 0.22337720718962312926e+4,
		 0.11274474380534949335e+3,
		 1.0
	};
	int 	negative = x < 0;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (negative) x = -x;

	if (x >= 0.5*M_LN_MAX_D) {
		x = 1.0;
	}
#define LN3D2	0.54930614433405484570e+0	/* ln(3)/2 */
	else if (x > LN3D2) {
		x = 0.5 - 1.0/(exp(x+x)+1.0);
		x += x;
	}
	else {
		/* ??? avoid underflow ??? */
		double g = x*x;
		x += x * g * POLYNOM2(g, p)/POLYNOM3(g, q);
	}
	return negative ? -x : x;
}
Esempio n. 9
0
static double
sinus(double x, int cos_flag)
{
	/*      Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/

	static double r[] = {
		-0.16666666666666665052e+0,
		 0.83333333333331650314e-2,
		-0.19841269841201840457e-3,
		 0.27557319210152756119e-5,
		-0.25052106798274584544e-7,
		 0.16058936490371589114e-9,
		-0.76429178068910467734e-12,
		 0.27204790957888846175e-14
	};

	double  y;
	int     neg = 1;

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (x < 0) {
		x = -x;
		neg = -1;
	}
	if (cos_flag) {
		neg = 1;
		y = M_PI_2 + x;
	}
	else    y = x;

	/* ??? avoid loss of significance, if y is too large, error ??? */

	y = y * M_1_PI + 0.5;

	if (y >= DBL_MAX/M_PI) return 0.0;

	/*      Use extended precision to calculate reduced argument.
		Here we used 12 bits of the mantissa for a1.
		Also split x in integer part x1 and fraction part x2.
	*/
#define A1 3.1416015625
#define A2 -8.908910206761537356617e-6
	{
		double x1, x2;

		modf(y, &y);
		if (modf(0.5*y, &x1)) neg = -neg;
		if (cos_flag) y -= 0.5;
		x2 = modf(x, &x1);
		x = x1 - y * A1;
		x += x2;
		x -= y * A2;
#undef A1
#undef A2
	}
 
	if (x < 0) {
		neg = -neg;
		x = -x;
	}

	/* ??? avoid underflow ??? */

	y = x * x;
	x += x * y * POLYNOM7(y, r);
	return neg==-1 ? -x : x;
}
Esempio n. 10
0
double
tan(double x)
{
	/*      Algorithm and coefficients from:
			"Software manual for the elementary functions"
			by W.J. Cody and W. Waite, Prentice-Hall, 1980
	*/

	int negative = x < 0;
	int invert = 0;
	double  y;
	static double   p[] = {
		 1.0,
		-0.13338350006421960681e+0,
		 0.34248878235890589960e-2,
		-0.17861707342254426711e-4
	};
	static double   q[] = {
		 1.0,
		-0.46671683339755294240e+0,
		 0.25663832289440112864e-1,
		-0.31181531907010027307e-3,
		 0.49819433993786512270e-6
	};

	if (__IsNan(x)) {
		errno = EDOM;
		return x;
	}
	if (negative) x = -x;
 
	/* ??? avoid loss of significance, error if x is too large ??? */

	y = x * M_2_PI + 0.5;

	if (y >= DBL_MAX/M_PI_2) return 0.0;

	/*      Use extended precision to calculate reduced argument.
		Here we used 12 bits of the mantissa for a1.
		Also split x in integer part x1 and fraction part x2.
	*/
    #define A1 1.57080078125
    #define A2 -4.454455103380768678308e-6
	{
		double x1, x2;

		modf(y, &y);
		if (modf(0.5*y, &x1)) invert = 1;
		x2 = modf(x, &x1);
		x = x1 - y * A1;
		x += x2;
		x -= y * A2;
    #undef A1
    #undef A2
	}

	/* ??? avoid underflow ??? */
	y = x * x;
	x += x * y * POLYNOM2(y, p+1);
	y = POLYNOM4(y, q);
	if (negative) x = -x;
	return invert ? -y/x : x/y;
}