float complex csinf(float complex z) { z = csinhf(cpackf(-cimagf(z), crealf(z))); return (cpackf(cimagf(z), -crealf(z))); }
float complex catanf(float complex z) { float complex w = catanhf(cpackf(cimagf(z), crealf(z))); return (cpackf(cimagf(w), crealf(w))); }
static float complex clog_for_large_values(float complex z) { float x, y; float ax, ay, t; x = crealf(z); y = cimagf(z); ax = fabsf(x); ay = fabsf(y); if (ax < ay) { t = ax; ax = ay; ay = t; } if (ax > FLT_MAX / 2) return (cpackf(logf(hypotf(x / m_e, y / m_e)) + 1, atan2f(y, x))); if (ax > QUARTER_SQRT_MAX || ay < SQRT_MIN) return (cpackf(logf(hypotf(x, y)), atan2f(y, x))); return (cpackf(logf(ax * ax + ay * ay) / 2, atan2f(y, x))); }
float complex ctanhf(float complex z) { float x, y; float t, beta, s, rho, denom; uint32_t hx, ix; x = crealf(z); y = cimagf(z); GET_FLOAT_WORD(hx, x); ix = hx & 0x7fffffff; if (ix >= 0x7f800000) { if (ix & 0x7fffff) return (cpackf(x, (y == 0 ? y : x * y))); SET_FLOAT_WORD(x, hx - 0x40000000); return (cpackf(x, copysignf(0, isinf(y) ? y : sinf(y) * cosf(y)))); } if (ix >= 0x41300000) { /* x >= 11 */ float exp_mx = expf(-fabsf(x)); return (cpackf(copysignf(1, x), 4 * sinf(y) * cosf(y) * exp_mx * exp_mx)); } t = tanf(y); beta = 1.0 + t * t; s = sinhf(x); rho = sqrtf(1 + s * s); denom = 1 + beta * s * s; return (cpackf((beta * rho * s) / denom, t / denom)); }
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 (cpackf(y + y, -INFINITY)); if (isinf(y)) return (cpackf(x + x, -y)); if (x == 0) return (cpackf(pio2_hi + pio2_lo, y + y)); return (cpackf(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 (cpackf(rx, ry)); } if (x == 1 && y == 0) return (cpackf(0, -y)); raise_inexact(); if (ax < SQRT_6_EPSILON / 4 && ay < SQRT_6_EPSILON / 4) return (cpackf(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 (cpackf(rx, ry)); }
float complex cacoshf(float complex z) { float complex w; float rx, ry; w = cacosf(z); rx = crealf(w); ry = cimagf(w); if (isnan(rx) && isnan(ry)) return (cpackf(ry, rx)); if (isnan(rx)) return (cpackf(fabsf(ry), rx)); if (isnan(ry)) return (cpackf(ry, ry)); return (cpackf(fabsf(ry), copysignf(rx, cimagf(z)))); }
float complex cprojf(float complex z) { if (!isinf(crealf(z)) && !isinf(cimagf(z))) return (z); else return (cpackf(INFINITY, copysignf(0.0, cimagf(z)))); }
float complex catanhf(float complex z) { float x, y, ax, ay, rx, ry; x = crealf(z); y = cimagf(z); ax = fabsf(x); ay = fabsf(y); if (y == 0 && ax <= 1) return (cpackf(atanhf(x), y)); if (x == 0) return (cpackf(x, atanf(y))); if (isnan(x) || isnan(y)) { if (isinf(x)) return (cpackf(copysignf(0, x), y + y)); if (isinf(y)) return (cpackf(copysignf(0, x), copysignf(pio2_hi + pio2_lo, y))); return (cpackf(x + 0.0L + (y + 0), x + 0.0L + (y + 0))); } if (ax > RECIP_EPSILON || ay > RECIP_EPSILON) return (cpackf(real_part_reciprocal(x, y), copysignf(pio2_hi + pio2_lo, y))); if (ax < SQRT_3_EPSILON / 2 && ay < SQRT_3_EPSILON / 2) { raise_inexact(); return (z); } if (ax == 1 && ay < FLT_EPSILON) rx = (m_ln2 - logf(ay)) / 2; else rx = log1pf(4 * ax / sum_squares(ax - 1, ay)) / 4; if (ax == 1) ry = atan2f(2, -ay) / 2; else if (ay < FLT_EPSILON) ry = atan2f(2 * ay, (1 - ax) * (1 + ax)) / 2; else ry = atan2f(2 * ay, (1 - ax) * (1 + ax) - ay * ay) / 2; return (cpackf(copysignf(rx, x), copysignf(ry, y))); }
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 (cpackf(expf(x), y)); GET_FLOAT_WORD(hx, x); /* cexp(0 + I y) = cos(y) + I sin(y) */ if ((hx & 0x7fffffff) == 0) return (cpackf(cosf(y), sinf(y))); if (hy >= 0x7f800000) { if ((hx & 0x7fffffff) != 0x7f800000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ return (cpackf(y - y, y - y)); } else if (hx & 0x80000000) { /* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */ return (cpackf(0.0, 0.0)); } else { /* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */ return (cpackf(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 (cpackf(exp_x * cosf(y), exp_x * sinf(y))); } }
float complex csqrtf(float complex z) { float a = crealf(z), b = cimagf(z); double t; /* Handle special cases. */ if (z == 0) return (cpackf(0, b)); if (isinf(b)) return (cpackf(INFINITY, b)); if (isnan(a)) { t = (b - b) / (b - b); /* raise invalid if b is not a NaN */ return (cpackf(a, t)); /* return NaN + NaN i */ } if (isinf(a)) { /* * csqrtf(inf + NaN i) = inf + NaN i * csqrtf(inf + y i) = inf + 0 i * csqrtf(-inf + NaN i) = NaN +- inf i * csqrtf(-inf + y i) = 0 + inf i */ if (signbit(a)) return (cpackf(fabsf(b - b), copysignf(a, b))); else return (cpackf(a, copysignf(b - b, b))); } /* * The remaining special case (b is NaN) is handled just fine by * the normal code path below. */ /* * We compute t in double precision to avoid overflow and to * provide correct rounding in nearly all cases. * This is Algorithm 312, CACM vol 10, Oct 1967. */ if (a >= 0) { t = sqrt((a + hypot(a, b)) * 0.5); return (cpackf(t, b / (2.0 * t))); } else { t = sqrt((-a + hypot(a, b)) * 0.5); return (cpackf(fabsf(b) / (2.0 * t), copysignf(t, b))); } }
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 (cpackf(x, y + y)); if (isinf(y)) return (cpackf(y, x + x)); if (y == 0) return (cpackf(x + x, y)); return (cpackf(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 (cpackf(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 (cpackf(copysignf(rx, x), copysignf(ry, y))); }
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))); }
float complex conjf(float complex z) { return (cpackf(crealf(z), -cimagf(z))); }
float complex cprojf(float complex z) { if (isinf(crealf(z)) || isinf(cimagf(z))) return cpackf(INFINITY, copysignf(0.0, crealf(z))); return z; }
float complex ccosf(float complex z) { return ccoshf(cpackf(-cimagf(z), crealf(z))); }
float complex catanhf(float complex z) { z = catanf(cpackf(-cimagf(z), crealf(z))); return cpackf(cimagf(z), -crealf(z)); }