long double _Complex _X_cplx_div_ix(long double b, long double _Complex w) { long double _Complex v; union { int i[3]; long double e; } bb, cc, dd; long double c, d, sc, sd, r; int eb, ec, ed, ew, i, j; /* * The following is equivalent to * * c = creall(*w); d = cimagl(*w); */ c = ((long double *)&w)[0]; d = ((long double *)&w)[1]; /* extract exponents to estimate |z| and |w| */ bb.e = b; eb = bb.i[2] & 0x7fff; cc.e = c; dd.e = d; ec = cc.i[2] & 0x7fff; ed = dd.i[2] & 0x7fff; ew = (ec > ed)? ec : ed; /* check for special cases */ if (ew >= 0x7fff) { /* w is inf or nan */ i = testinfl(c); j = testinfl(d); if (i | j) { /* w is infinite */ c = ((cc.i[2] << 16) < 0)? -0.0f : 0.0f; d = ((dd.i[2] << 16) < 0)? -0.0f : 0.0f; } else /* w is nan */ b += c + d; ((long double *)&v)[0] = b * d; ((long double *)&v)[1] = b * c; return (v); } if (ew == 0 && (cc.i[1] | cc.i[0] | dd.i[1] | dd.i[0]) == 0) { /* w is zero; multiply b by 1/Re(w) - I * Im(w) */ c = 1.0f / c; j = testinfl(b); if (j) { /* b is infinite */ b = j; } ((long double *)&v)[0] = (b == 0.0f)? b * c : b * d; ((long double *)&v)[1] = b * c; return (v); } if (eb >= 0x7fff) { /* a is inf or nan */ ((long double *)&v)[0] = b * d; ((long double *)&v)[1] = b * c; return (v); } /* * Compute the real and imaginary parts of the quotient, * scaling to avoid overflow or underflow. */ ew = (ew - 0x3800) >> 12; sc = c * scl[ew + 4].e; sd = d * scl[ew + 4].e; r = sc * sc + sd * sd; eb = (eb - 0x3800) >> 12; b = (b * scl[eb + 4].e) / r; eb -= (ew + ew); ec = (ec - 0x3800) >> 12; c = (c * scl[ec + 4].e) * b; ec += eb; ed = (ed - 0x3800) >> 12; d = (d * scl[ed + 4].e) * b; ed += eb; /* compensate for scaling */ sc = scl[3].e; /* 2^4080 */ if (ec < 0) { ec = -ec; sc = scl[5].e; /* 2^-4080 */ } while (ec--) c *= sc; sd = scl[3].e; if (ed < 0) { ed = -ed; sd = scl[5].e; } while (ed--) d *= sd; ((long double *)&v)[0] = d; ((long double *)&v)[1] = c; return (v); }
long double _Complex _Q_cplx_div_rx(const long double *pa, const long double _Complex *w) { long double _Complex v; #else void _Q_cplx_div_rx(long double _Complex *v, const long double *pa, const long double _Complex *w) { #endif union { int i[4]; long double q; } aa, cc, dd; long double a, c, d, sc, sd, r; int ha, hc, hd, hw, i, j; a = *pa; /* * The following is equivalent to * * c = creall(*w); d = cimagl(*w); */ c = ((long double *)w)[0]; d = ((long double *)w)[1]; /* extract high-order words to estimate |a| and |w| */ aa.q = a; ha = aa.i[0] & ~0x80000000; cc.q = c; dd.q = d; hc = cc.i[0] & ~0x80000000; hd = dd.i[0] & ~0x80000000; hw = (hc > hd)? hc : hd; /* check for special cases */ if (hw >= 0x7fff0000) { /* w is inf or nan */ i = testinfl(c); j = testinfl(d); if (i | j) { /* w is infinite */ c = (cc.i[0] < 0)? -0.0l : 0.0l; d = (dd.i[0] < 0)? -0.0l : 0.0l; } else /* w is nan */ a += c + d; c *= a; d *= -a; goto done; } if (hw == 0 && (cc.i[1] | cc.i[2] | cc.i[3] | dd.i[1] | dd.i[2] | dd.i[3]) == 0) { /* w is zero; multiply a by 1/Re(w) - I * Im(w) */ c = 1.0l / c; i = testinfl(a); if (i) { /* a is infinite */ a = i; } c *= a; d = (a == 0.0l)? c : -a * d; goto done; } if (ha >= 0x7fff0000) { /* a is inf or nan */ c *= a; d *= -a; goto done; } /* * Compute the real and imaginary parts of the quotient, * scaling to avoid overflow or underflow. */ hw = (hw - 0x3fff0000) >> 16; sc = c; sd = d; _Q_scl(&sc, -hw); _Q_scl(&sd, -hw); r = sc * sc + sd * sd; ha = (ha - 0x3fff0000) >> 16; _Q_scl(&a, -ha); a /= r; ha -= (hw + hw); hc = (hc - 0x3fff0000) >> 16; _Q_scl(&c, -hc); c *= a; hc += ha; hd = (hd - 0x3fff0000) >> 16; _Q_scl(&d, -hd); d *= -a; hd += ha; /* compensate for scaling */ _Q_scle(&c, hc); _Q_scle(&d, hd); done: #ifdef __sparcv9 ((long double *)&v)[0] = c; ((long double *)&v)[1] = d; return (v); #else ((long double *)v)[0] = c; ((long double *)v)[1] = d; #endif }