Ejemplo n.º 1
0
float complex
cacosf(float complex z)
{
	float x, y, ax, ay, rx, ry, B, sqrt_A2mx2, new_x;
	int sx, sy;
	int B_is_usable;
	float complex w;

	x = crealf(z);
	y = cimagf(z);
	sx = signbit(x);
	sy = signbit(y);
	ax = fabsf(x);
	ay = fabsf(y);

	if (isnan(x) || isnan(y)) {
		if (isinf(x))
			return (CMPLXF(y + y, -INFINITY));
		if (isinf(y))
			return (CMPLXF(x + x, -y));
		if (x == 0)
			return (CMPLXF(pio2_hi + pio2_lo, y + y));
		return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
	}

	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
		w = clog_for_large_values(z);
		rx = fabsf(cimagf(w));
		ry = crealf(w) + m_ln2;
		if (sy == 0)
			ry = -ry;
		return (CMPLXF(rx, ry));
	}

	if (x == 1 && y == 0)
		return (CMPLXF(0, -y));

	raise_inexact();

	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
		return (CMPLXF(pio2_hi - (x - pio2_lo), -y));

	do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x);
	if (B_is_usable) {
		if (sx == 0)
			rx = acosf(B);
		else
			rx = acosf(-B);
	} else {
		if (sx == 0)
			rx = atan2f(sqrt_A2mx2, new_x);
		else
			rx = atan2f(sqrt_A2mx2, -new_x);
	}
	if (sy == 0)
		ry = -ry;
	return (CMPLXF(rx, ry));
}
Ejemplo n.º 2
0
long double complex
cacosl(long double complex z)
{
	long double x, y, ax, ay, rx, ry, B, sqrt_A2mx2, new_x;
	int sx, sy;
	int B_is_usable;
	long double complex w;

	x = creall(z);
	y = cimagl(z);
	sx = signbit(x);
	sy = signbit(y);
	ax = fabsl(x);
	ay = fabsl(y);

	if (isnan(x) || isnan(y)) {
		if (isinf(x))
			return (CMPLXL(y + y, -INFINITY));
		if (isinf(y))
			return (CMPLXL(x + x, -y));
		if (x == 0)
			return (CMPLXL(pio2_hi + pio2_lo, y + y));
		return (CMPLXL(nan_mix(x, y), nan_mix(x, y)));
	}

	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
		w = clog_for_large_values(z);
		rx = fabsl(cimagl(w));
		ry = creall(w) + m_ln2;
		if (sy == 0)
			ry = -ry;
		return (CMPLXL(rx, ry));
	}

	if (x == 1 && y == 0)
		return (CMPLXL(0, -y));

	raise_inexact();

	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
		return (CMPLXL(pio2_hi - (x - pio2_lo), -y));

	do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x);
	if (B_is_usable) {
		if (sx == 0)
			rx = acosl(B);
		else
			rx = acosl(-B);
	} else {
		if (sx == 0)
			rx = atan2l(sqrt_A2mx2, new_x);
		else
			rx = atan2l(sqrt_A2mx2, -new_x);
	}
	if (sy == 0)
		ry = -ry;
	return (CMPLXL(rx, ry));
}
Ejemplo n.º 3
0
/*
 * casinh(z) = z + O(z^3)   as z -> 0
 *
 * casinh(z) = sign(x)*clog(sign(x)*z) + O(1/z^2)   as z -> infinity
 * The above formula works for the imaginary part as well, because
 * Im(casinh(z)) = sign(x)*atan2(sign(x)*y, fabs(x)) + O(y/z^3)
 *    as z -> infinity, uniformly in y
 */
double complex
casinh(double complex z)
{
	double x, y, ax, ay, rx, ry, B, sqrt_A2my2, new_y;
	int B_is_usable;
	double complex w;

	x = creal(z);
	y = cimag(z);
	ax = fabs(x);
	ay = fabs(y);

	if (isnan(x) || isnan(y)) {
		/* casinh(+-Inf + I*NaN) = +-Inf + I*NaN */
		if (isinf(x))
			return (CMPLX(x, y + y));
		/* casinh(NaN + I*+-Inf) = opt(+-)Inf + I*NaN */
		if (isinf(y))
			return (CMPLX(y, x + x));
		/* casinh(NaN + I*0) = NaN + I*0 */
		if (y == 0)
			return (CMPLX(x + x, y));
		/*
		 * All other cases involving NaN return NaN + I*NaN.
		 * C99 leaves it optional whether to raise invalid if one of
		 * the arguments is not NaN, so we opt not to raise it.
		 */
		return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
	}

	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
		/* clog...() will raise inexact unless x or y is infinite. */
		if (signbit(x) == 0)
			w = clog_for_large_values(z) + m_ln2;
		else
			w = clog_for_large_values(-z) + m_ln2;
		return (CMPLX(copysign(creal(w), x), copysign(cimag(w), y)));
	}

	/* Avoid spuriously raising inexact for z = 0. */
	if (x == 0 && y == 0)
		return (z);

	/* All remaining cases are inexact. */
	raise_inexact();

	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
		return (z);

	do_hard_work(ax, ay, &rx, &B_is_usable, &B, &sqrt_A2my2, &new_y);
	if (B_is_usable)
		ry = asin(B);
	else
		ry = atan2(new_y, sqrt_A2my2);
	return (CMPLX(copysign(rx, x), copysign(ry, y)));
}
Ejemplo n.º 4
0
float complex
casinhf(float complex z)
{
	float x, y, ax, ay, rx, ry, B, sqrt_A2my2, new_y;
	int B_is_usable;
	float complex w;

	x = crealf(z);
	y = cimagf(z);
	ax = fabsf(x);
	ay = fabsf(y);

	if (isnan(x) || isnan(y)) {
		if (isinf(x))
			return (CMPLXF(x, y + y));
		if (isinf(y))
			return (CMPLXF(y, x + x));
		if (y == 0)
			return (CMPLXF(x + x, y));
		return (CMPLXF(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
	}

	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
		if (signbit(x) == 0)
			w = clog_for_large_values(z) + m_ln2;
		else
			w = clog_for_large_values(-z) + m_ln2;
		return (CMPLXF(copysignf(crealf(w), x),
		    copysignf(cimagf(w), y)));
	}

	if (x == 0 && y == 0)
		return (z);

	raise_inexact();

	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
		return (z);

	do_hard_work(ax, ay, &rx, &B_is_usable, &B, &sqrt_A2my2, &new_y);
	if (B_is_usable)
		ry = asinf(B);
	else
		ry = atan2f(new_y, sqrt_A2my2);
	return (CMPLXF(copysignf(rx, x), copysignf(ry, y)));
}
Ejemplo n.º 5
0
long double complex
casinhl(long double complex z)
{
	long double x, y, ax, ay, rx, ry, B, sqrt_A2my2, new_y;
	int B_is_usable;
	long double complex w;

	x = creall(z);
	y = cimagl(z);
	ax = fabsl(x);
	ay = fabsl(y);

	if (isnan(x) || isnan(y)) {
		if (isinf(x))
			return (CMPLXL(x, y + y));
		if (isinf(y))
			return (CMPLXL(y, x + x));
		if (y == 0)
			return (CMPLXL(x + x, y));
		return (CMPLXL(nan_mix(x, y), nan_mix(x, y)));
	}

	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
		if (signbit(x) == 0)
			w = clog_for_large_values(z) + m_ln2;
		else
			w = clog_for_large_values(-z) + m_ln2;
		return (CMPLXL(copysignl(creall(w), x),
		    copysignl(cimagl(w), y)));
	}

	if (x == 0 && y == 0)
		return (z);

	raise_inexact();

	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
		return (z);

	do_hard_work(ax, ay, &rx, &B_is_usable, &B, &sqrt_A2my2, &new_y);
	if (B_is_usable)
		ry = asinl(B);
	else
		ry = atan2l(new_y, sqrt_A2my2);
	return (CMPLXL(copysignl(rx, x), copysignl(ry, y)));
}
Ejemplo n.º 6
0
/*
 * cacos(z) = PI/2 - casin(z)
 * but do the computation carefully so cacos(z) is accurate when z is
 * close to 1.
 *
 * cacos(z) = PI/2 - z + O(z^3)   as z -> 0
 *
 * cacos(z) = -sign(y)*I*clog(z) + O(1/z^2)   as z -> infinity
 * The above formula works for the real part as well, because
 * Re(cacos(z)) = atan2(fabs(y), x) + O(y/z^3)
 *    as z -> infinity, uniformly in y
 */
double complex
cacos(double complex z)
{
	double x, y, ax, ay, rx, ry, B, sqrt_A2mx2, new_x;
	int sx, sy;
	int B_is_usable;
	double complex w;

	x = creal(z);
	y = cimag(z);
	sx = signbit(x);
	sy = signbit(y);
	ax = fabs(x);
	ay = fabs(y);

	if (isnan(x) || isnan(y)) {
		/* cacos(+-Inf + I*NaN) = NaN + I*opt(-)Inf */
		if (isinf(x))
			return (CMPLX(y + y, -INFINITY));
		/* cacos(NaN + I*+-Inf) = NaN + I*-+Inf */
		if (isinf(y))
			return (CMPLX(x + x, -y));
		/* cacos(0 + I*NaN) = PI/2 + I*NaN with inexact */
		if (x == 0)
			return (CMPLX(pio2_hi + pio2_lo, y + y));
		/*
		 * All other cases involving NaN return NaN + I*NaN.
		 * C99 leaves it optional whether to raise invalid if one of
		 * the arguments is not NaN, so we opt not to raise it.
		 */
		return (CMPLX(x + 0.0L + (y + 0), x + 0.0L + (y + 0)));
	}

	if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) {
		/* clog...() will raise inexact unless x or y is infinite. */
		w = clog_for_large_values(z);
		rx = fabs(cimag(w));
		ry = creal(w) + m_ln2;
		if (sy == 0)
			ry = -ry;
		return (CMPLX(rx, ry));
	}

	/* Avoid spuriously raising inexact for z = 1. */
	if (x == 1 && y == 0)
		return (CMPLX(0, -y));

	/* All remaining cases are inexact. */
	raise_inexact();

	if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4)
		return (CMPLX(pio2_hi - (x - pio2_lo), -y));

	do_hard_work(ay, ax, &ry, &B_is_usable, &B, &sqrt_A2mx2, &new_x);
	if (B_is_usable) {
		if (sx == 0)
			rx = acos(B);
		else
			rx = acos(-B);
	} else {
		if (sx == 0)
			rx = atan2(sqrt_A2mx2, new_x);
		else
			rx = atan2(sqrt_A2mx2, -new_x);
	}
	if (sy == 0)
		ry = -ry;
	return (CMPLX(rx, ry));
}