diff options
author | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2011-01-07 20:02:45 +0000 |
---|---|---|
committer | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2011-01-07 20:02:45 +0000 |
commit | a0a24dd6f60dbcaf09942807f86259d9f1ca16f9 (patch) | |
tree | 0a4a590505d4dc948f699e846fd26a19ba7cb9a5 /src/tan.c | |
parent | e7819e979c2d86ecbcd411ccd2b66834257c7abb (diff) | |
download | mpc-a0a24dd6f60dbcaf09942807f86259d9f1ca16f9.tar.gz |
tan: use sin_cos, gains about a third of the running time in ttan
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@862 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'src/tan.c')
-rw-r--r-- | src/tan.c | 24 |
1 files changed, 10 insertions, 14 deletions
@@ -1,6 +1,6 @@ /* mpc_tan -- tangent of a complex number. -Copyright (C) 2008, 2009, 2010 Philippe Th\'eveny, Andreas Enge, Paul Zimmermann +Copyright (C) 2008, 2009, 2010, 2011 Philippe Th\'eveny, Andreas Enge, Paul Zimmermann This file is part of the MPC Library. @@ -183,7 +183,6 @@ mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) do { mpfr_exp_t k, exr, eyr, eyi, ezr; - int isinf = 0; ok = 0; @@ -195,23 +194,19 @@ mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) /* rounding away from zero: except in the cases x=0 or y=0 (processed above), sin x and cos y are never exact, so rounding away from 0 is rounding towards 0 and adding one ulp to the absolute value */ - mpc_sin (x, op, MPC_RNDZZ); - isinf = mpfr_inf_p (MPC_RE (x)) || mpfr_inf_p (MPC_IM (x)); - /* if the real or imaginary part of x is infinite, it means that Im(op) - was large, in which case the result is - sign(tan(Re(op)))*0 + sign(Im(op))*I, - where sign(tan(Re(op))) = sign(Re(x))*sign(Re(y)) */ + mpc_sin_cos (x, y, op, MPC_RNDZZ, MPC_RNDZZ); MPFR_ADD_ONE_ULP (MPC_RE (x)); MPFR_ADD_ONE_ULP (MPC_IM (x)); - MPC_ASSERT (mpfr_zero_p (MPC_RE (x)) == 0); - exr = mpfr_get_exp (MPC_RE (x)); - mpc_cos (y, op, MPC_RNDZZ); - isinf = isinf || mpfr_inf_p (MPC_RE (y)) || mpfr_inf_p (MPC_IM (y)); MPFR_ADD_ONE_ULP (MPC_RE (y)); MPFR_ADD_ONE_ULP (MPC_IM (y)); + MPC_ASSERT (mpfr_zero_p (MPC_RE (x)) == 0); - if (isinf) - { + if ( mpfr_inf_p (MPC_RE (x)) || mpfr_inf_p (MPC_IM (x)) + || mpfr_inf_p (MPC_RE (y)) || mpfr_inf_p (MPC_IM (y))) { + /* If the real or imaginary part of x is infinite, it means that + Im(op) was large, in which case the result is + sign(tan(Re(op)))*0 + sign(Im(op))*I, + where sign(tan(Re(op))) = sign(Re(x))*sign(Re(y)). */ int inex_re, inex_im; mpfr_set_ui (MPC_RE (rop), 0, GMP_RNDN); if (mpfr_sgn (MPC_RE (x)) * mpfr_sgn (MPC_RE (y)) < 0) @@ -235,6 +230,7 @@ mpc_tan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) goto end; } + exr = mpfr_get_exp (MPC_RE (x)); eyr = mpfr_get_exp (MPC_RE (y)); eyi = mpfr_get_exp (MPC_IM (y)); |