struct xpr cxarg (struct cxpr z) { int rs, is; rs = xsgn (&z.re); is = xsgn (&z.im); if (rs > 0) return xatan (xdiv (z.im, z.re)); else if (rs < 0) { z.re.nmm[0] ^= xM_sgn; z.im.nmm[0] ^= xM_sgn; if (is >= 0) return xadd (xPi, xatan (xdiv (z.im, z.re)), 0); else return xadd (xatan (xdiv (z.im, z.re)), xPi, 1); } else /* z.re is zero ! */ { if (!xsigerr (is == 0, XEDOM, "cxarg()")) return (is > 0 ? xPi2 : xneg (xPi2)); else return xneg (xPi2); /* Dummy value :) */ } }
static double satan(double arg) { if(arg < sq2m1) return xatan(arg); if(arg > sq2p1) return PIO2 - xatan(1/arg); return PIO2/2 + xatan((arg-1)/(arg+1)); }
void test_trig() { double x; double y; RPN::Context cxt; cxt.insert("x", new RPN::VariableNode(&x)); cxt.insert("y", new RPN::VariableNode(&y)); RPN::Expression xsin("sin x", cxt); RPN::Expression xcos("cos x", cxt); RPN::Expression xtan("tan x", cxt); RPN::Expression xsec("sec x", cxt); RPN::Expression xcsc("csc x", cxt); RPN::Expression xcot("cot x", cxt); RPN::Expression xasin("asin x", cxt); RPN::Expression xacos("acos x", cxt); RPN::Expression xatan("atan x", cxt); RPN::Expression xasec("asec x", cxt); RPN::Expression xacsc("acsc x", cxt); RPN::Expression xacot("acot x", cxt); RPN::Expression xatan2("atan2(x, y)", cxt); RPN::Expression xacot2("acot2(x, y)", cxt); for(x = -RPN::Constants::PI; x < RPN::Constants::PI; x += 0.097) { insist_equal(xsin.evaluate(), sin(x)); insist_equal(xcos.evaluate(), cos(x)); insist_equal(xtan.evaluate(), tan(x)); insist_equal(xsec.evaluate(), 1.0/cos(x)); insist_equal(xcsc.evaluate(), 1.0/sin(x)); insist_equal(xcot.evaluate(), 1.0/tan(x)); } for(x = -1; x < 1; x += 0.043) { insist_equal(xasin.evaluate(), asin(x)); insist_equal(xacos.evaluate(), acos(x)); insist_equal(xatan.evaluate(), atan(x)); insist_equal(xasec.evaluate(), acos(1.0/x)); insist_equal(xacsc.evaluate(), asin(1.0/x)); insist_equal(xacot.evaluate(), atan(1.0/x)); } for(x = -1; x < 1; x+= 0.069) { for(y = -1; y < 1; y += 0.73) { insist_equal(xatan2.evaluate(), atan2(x, y)); insist_equal(xacot2.evaluate(), atan2(y, x)); } } }
int main (void) { struct xpr z, f, c; int k; printf (" Test of Inverse Trig Functions\n"); printf ("\n Atan:\n"); for (k = 0; k < 3; ++k) { switch (k) { case 0: z = dbltox (.5); break; case 1: z = dbltox (1.); break; case 2: z = dbltox (-2.); break; } /* compute extended precision arctangent and tangent */ f = xatan (z); c = xtan (f); printf (" %8.4f ", xtodbl (z)); xprxpr (f, decd); printf ("\n check tan= "); xprxpr (c, decd); putchar ('\n'); } printf ("\n Asin:\n"); for (k = 0; k < 3; ++k) { switch (k) { case 0: z = dbltox (.5); break; case 1: z = dbltox (.75); break; case 2: z = dbltox (.25); break; } /* compute extended precision arcsin and sine */ f = xasin (z); c = xsin (f); printf (" %8.4f ", xtodbl (z)); xprxpr (f, decd); printf ("\n check sin= "); xprxpr (c, decd); putchar ('\n'); } printf ("\n Acos:\n"); for (k = 0; k < 3; ++k) { switch (k) { case 0: z = dbltox (.5); break; case 1: z = dbltox (.75); break; case 2: z = dbltox (.25); break; } /* compute extended precision arccos and cosine */ f = xacos (z); c = xcos (f); printf (" %8.4f ", xtodbl (z)); xprxpr (f, decd); printf ("\n check cos= "); xprxpr (c, decd); putchar ('\n'); } return 0; }