dcomplex csinh(dcomplex z) { double t, x, y, S, C; int hx, ix, lx, hy, iy, ly, n; dcomplex ans; x = D_RE(z); y = D_IM(z); hx = HI_WORD(x); lx = LO_WORD(x); ix = hx & 0x7fffffff; hy = HI_WORD(y); ly = LO_WORD(y); iy = hy & 0x7fffffff; x = fabs(x); y = fabs(y); (void) sincos(y, &S, &C); if (ix >= 0x403c0000) { /* |x| > 28 = prec/2 (14,28,34,60) */ if (ix >= 0x40862E42) { /* |x| > 709.78... ~ log(2**1024) */ if (ix >= 0x7ff00000) { /* |x| is inf or NaN */ if ((iy | ly) == 0) { D_RE(ans) = x; D_IM(ans) = y; } else if (iy >= 0x7ff00000) { D_RE(ans) = x; D_IM(ans) = x - y; } else { D_RE(ans) = C * x; D_IM(ans) = S * x; } } else { /* return exp(x)=t*2**n */ t = __k_cexp(x, &n); D_RE(ans) = scalbn(C * t, n - 1); D_IM(ans) = scalbn(S * t, n - 1); } } else { t = exp(x) * 0.5; D_RE(ans) = C * t; D_IM(ans) = S * t; } } else { if ((ix | lx) == 0) { /* x = 0, return (0,S) */ D_RE(ans) = 0.0; D_IM(ans) = S; } else { D_RE(ans) = C * sinh(x); D_IM(ans) = S * cosh(x); } } if (hx < 0) D_RE(ans) = -D_RE(ans); if (hy < 0) D_IM(ans) = -D_IM(ans); return (ans); }
dcomplex ccos(dcomplex z) { double x, y; x = D_RE(z); y = D_IM(z); D_RE(z) = y; D_IM(z) = -x; return (ccosh(z)); }
dcomplex csqrt(dcomplex z) { dcomplex ans; double x, y, t, ax, ay; int n, ix, iy, hx, hy, lx, ly; x = D_RE(z); y = D_IM(z); hx = HI_WORD(x); lx = LO_WORD(x); hy = HI_WORD(y); ly = LO_WORD(y); ix = hx & 0x7fffffff; iy = hy & 0x7fffffff; ay = fabs(y); ax = fabs(x); if (ix >= 0x7ff00000 || iy >= 0x7ff00000) { /* x or y is Inf or NaN */ if (ISINF(iy, ly)) D_IM(ans) = D_RE(ans) = ay; else if (ISINF(ix, lx)) { if (hx > 0) { D_RE(ans) = ax; D_IM(ans) = ay * zero; } else { D_RE(ans) = ay * zero; D_IM(ans) = ax; } } else D_IM(ans) = D_RE(ans) = ax + ay; } else if ((iy | ly) == 0) { /* y = 0 */ if (hx >= 0) { D_RE(ans) = sqrt(ax); D_IM(ans) = zero; } else { D_IM(ans) = sqrt(ax); D_RE(ans) = zero; } } else if (ix >= iy) { n = (ix - iy) >> 20; if (n >= 30) { /* x >> y or y=0 */ t = sqrt(ax); } else if (ix >= 0x5f300000) { /* x > 2**500 */ ax *= twom601; y *= twom601; t = two300 * sqrt(ax + sqrt(ax * ax + y * y)); } else if (iy < 0x20b00000) { /* y < 2**-500 */ ax *= two599; y *= two599; t = twom300 * sqrt(ax + sqrt(ax * ax + y * y)); } else t = sqrt(half * (ax + sqrt(ax * ax + ay * ay))); if (hx >= 0) { D_RE(ans) = t; D_IM(ans) = ay / (t + t); } else { D_IM(ans) = t; D_RE(ans) = ay / (t + t); } } else {
dcomplex casinh(dcomplex z) { dcomplex w, r, ans; D_RE(w) = -D_IM(z); D_IM(w) = D_RE(z); r = casin(w); D_RE(ans) = D_IM(r); D_IM(ans) = -D_RE(r); return (ans); }
dcomplex ctan(dcomplex z) { double x, y; dcomplex ans, ct; x = D_RE(z); y = D_IM(z); D_RE(z) = y; D_IM(z) = -x; ct = ctanh(z); D_RE(ans) = -D_IM(ct); D_IM(ans) = D_RE(ct); return (ans); }