Example #1
0
float complex
csinhf(float complex z)
{
	float x, y, h;
	int32_t hx, hy, ix, iy;

	x = crealf(z);
	y = cimagf(z);

	GET_FLOAT_WORD(hx, x);
	GET_FLOAT_WORD(hy, y);

	ix = 0x7fffffff & hx;
	iy = 0x7fffffff & hy;

	if (ix < 0x7f800000 && iy < 0x7f800000) {
		if (iy == 0)
			return (cpackf(sinhf(x), y));
		if (ix < 0x41100000)	/* small x: normal case */
			return (cpackf(sinhf(x) * cosf(y), coshf(x) * sinf(y)));

		/* |x| >= 9, so cosh(x) ~= exp(|x|) */
		if (ix < 0x42b17218) {
			/* x < 88.7: expf(|x|) won't overflow */
			h = expf(fabsf(x)) * 0.5f;
			return (cpackf(copysignf(h, x) * cosf(y), h * sinf(y)));
		} else if (ix < 0x4340b1e7) {
			/* x < 192.7: scale to avoid overflow */
			z = __ldexp_cexpf(cpackf(fabsf(x), y), -1);
			return (cpackf(crealf(z) * copysignf(1, x), cimagf(z)));
		} else {
			/* x >= 192.7: the result always overflows */
			h = huge * x;
			return (cpackf(h * cosf(y), h * h * sinf(y)));
		}
	}

	if (ix == 0 && iy >= 0x7f800000)
		return (cpackf(copysignf(0, x * (y - y)), y - y));

	if (iy == 0 && ix >= 0x7f800000) {
		if ((hx & 0x7fffff) == 0)
			return (cpackf(x, y));
		return (cpackf(x, copysignf(0, y)));
	}

	if (ix < 0x7f800000 && iy >= 0x7f800000)
		return (cpackf(y - y, x * (y - y)));

	if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
		if (iy >= 0x7f800000)
			return (cpackf(x * x, x * (y - y)));
		return (cpackf(x * cosf(y), INFINITY * sinf(y)));
	}

	return (cpackf((x * x) * (y - y), (x + x) * (y - y)));
}
Example #2
0
float complex
cexpf(float complex z)
{
	float x, y, exp_x;
	uint32_t hx, hy;

	x = crealf(z);
	y = cimagf(z);

	GET_FLOAT_WORD(hy, y);
	hy &= 0x7fffffff;

	/* cexp(x + I 0) = exp(x) + I 0 */
	if (hy == 0)
		return (CMPLXF(expf(x), y));
	GET_FLOAT_WORD(hx, x);
	/* cexp(0 + I y) = cos(y) + I sin(y) */
	if ((hx & 0x7fffffff) == 0)
		return (CMPLXF(cosf(y), sinf(y)));

	if (hy >= 0x7f800000) {
		if ((hx & 0x7fffffff) != 0x7f800000) {
			/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
			return (CMPLXF(y - y, y - y));
		} else if (hx & 0x80000000) {
			/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
			return (CMPLXF(0.0, 0.0));
		} else {
			/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
			return (CMPLXF(x, y - y));
		}
	}

	if (hx >= exp_ovfl && hx <= cexp_ovfl) {
		/*
		 * x is between 88.7 and 192, so we must scale to avoid
		 * overflow in expf(x).
		 */
		return (__ldexp_cexpf(z, 0));
	} else {
		/*
		 * Cases covered here:
		 *  -  x < exp_ovfl and exp(x) won't overflow (common case)
		 *  -  x > cexp_ovfl, so exp(x) * s overflows for all s > 0
		 *  -  x = +-Inf (generated by exp())
		 *  -  x = NaN (spurious inexact exception from y)
		 */
		exp_x = expf(x);
		return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y)));
	}
}