int cxrec (struct cxpr z, struct cxpr *w) { struct xpr x; int sa, sb, ea, eb; if (xprcmp (&z.re, &xZero) == 0 && xprcmp (&z.im, &xZero) == 0) return 0; else { sa = z.re.nmm[0] & xM_sgn; sb = z.im.nmm[0] & xM_sgn; ea = (z.re.nmm[0] &= xM_exp) - xBias; eb = (z.im.nmm[0] &= xM_exp) - xBias; if (ea > eb + XBOUND) x = z.re; else if (eb > ea + XBOUND) x = z.im; else { z.re.nmm[0] -= eb; z.im.nmm[0] = xBias; x = xsqrt (xadd (xmul (z.re, z.re), xmul (z.im, z.im), 0)); x.nmm[0] += eb; z.re.nmm[0] += eb; z.im.nmm[0] += eb; } w->re = xdiv (xdiv (z.re, x), x); w->im = xdiv (xdiv (z.im, x), x); w->re.nmm[0] |= sa; w->im.nmm[0] |= xM_sgn ^ sb; return 1; } }
struct xpr cxabs (struct cxpr z) { struct xpr x; int ea, eb; if (xprcmp (&z.re, &xZero) == 0 && xprcmp (&z.im, &xZero) == 0) return xZero; else { ea = (z.re.nmm[0] &= xM_exp) - xBias; eb = (z.im.nmm[0] &= xM_exp) - xBias; if (ea > eb + XBOUND) return z.re; else if (eb > ea + XBOUND) return z.im; else { z.re.nmm[0] -= eb; z.im.nmm[0] = xBias; x = xsqrt (xadd (xmul (z.re, z.re), xmul (z.im, z.im), 0)); x.nmm[0] += eb; return x; } } }
struct cxpr cxacosh (struct cxpr z) { struct cxpr w; struct xpr ls, rs; w = cxsqrt (cxsub (cxsqr (z), cxOne)); ls = cxabs (cxsum (z, w)); rs = xmul (xVSV, cxabs (z)); if (xprcmp (&ls, &rs) < 0) return cxneg (cxlog (cxsub (z, w))); else return cxlog (cxsum (z, w)); }
int main (int na, char **av) { struct xpr s, t, f; char nbx[64], nby[64]; FILE *fp; if (na != 2) { printf ("para: input_file\n"); exit (-1); } fp = fopen (*++av, "r"); printf (" Test of Elementary Operations\n"); while (fscanf (fp, "%s %s", nbx, nby) != EOF) { s = atox (nbx); t = atox (nby); printf ("\n x= "); xprxpr (s, decd); printf ("\n y= "); xprxpr (t, decd); /* extended precision addition */ printf ("\nadd\n"); f = xadd (s, t, 0); printf (" %16.10f\n", xtodbl (f)); xprxpr (f, decd); /* extended precision subtraction */ printf ("\nsubtract\n"); f = xadd (s, t, 1); printf (" %16.10f\n", xtodbl (f)); xprxpr (f, decd); /* extended precision multiplication */ printf ("\nmultiply\n"); f = xmul (s, t); printf (" %16.10f\n", xtodbl (f)); xprxpr (f, decd); /* extended precision division */ printf ("\ndivide\n"); f = xdiv (s, t); printf (" %16.10f\n", xtodbl (f)); xprxpr (f, decd); } putchar ('\n'); return 0; }
struct xpr xsin (struct xpr z) { int k; z = rred (z, 's', &k); if (x_exp (&z) >= xK_lin) { z = c_tan (xpr2 (z, -1)); z = xdiv (xpr2 (z, 1), xadd (xOne, xmul (z, z), 0)); } if ((k)) return xneg (z); else return z; }
struct cxpr cxasinh (struct cxpr z) { struct cxpr w; struct xpr ls, rs; /* In this way, cxasinh() works fine also with real numbers */ /* very near to -oo. */ w = cxsqrt (cxsum (cxOne, cxsqr (z))); ls = cxabs (cxsum (z, w)); rs = xmul (xVSV, cxabs (z)); if (xprcmp (&ls, &rs) < 0) return cxneg (cxlog (cxsub (w, z))); else return cxlog (cxsum (z, w)); }
struct xpr xcos (struct xpr z) { int k; z = rred (z, 'c', &k); if (x_exp (&z) < xK_lin) { if ((k)) return xneg (xOne); else return xOne; } z = c_tan (xpr2 (z, -1)); z = xmul (z, z); z = xdiv (xadd (xOne, z, 1), xadd (xOne, z, 0)); if ((k)) return xneg (z); else return z; }
static struct xpr c_tan (struct xpr z) { struct xpr s, f, d; int m; unsigned short k; if (x_exp (&z) < xK_lin) return z; s = xneg (xmul (z, z)); for (k = 1; k <= XDIM && s.nmm[k] == 0; k++); if ((xsigerr (s.nmm[0] == 0xffff && k > XDIM, XFPOFLOW, NULL))) return xZero; else { f = xZero; for (d = inttox (m = xMS_trg); m > 1;) { f = xdiv (s, xadd (d, f, 0)); d = inttox (m -= 2); } return xdiv (z, xadd (d, f, 0)); } }
vector3D MakeNormal(point3D &p1, point3D &p2, point3D &p3) { vector3D ans = xmul(p2-p1, p3-p1); normal(ans); return ans; }