diff options
author | zimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2010-08-31 12:30:40 +0000 |
---|---|---|
committer | zimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2010-08-31 12:30:40 +0000 |
commit | da7ecc6ae4f8836ca507e8c7de2e56abc372c5fc (patch) | |
tree | fac5da9dbfd3e46f02ebd1bdca9eaef9c386b2b5 /src/acos.c | |
parent | 8a098efd6bc329d4474bb419d704fb63d319f875 (diff) | |
download | mpc-da7ecc6ae4f8836ca507e8c7de2e56abc372c5fc.tar.gz |
fixed integer undefined behaviors reported by John Regehr (#10838)
git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@817 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'src/acos.c')
-rw-r--r-- | src/acos.c | 31 |
1 files changed, 17 insertions, 14 deletions
@@ -1,6 +1,6 @@ /* mpc_acos -- arccosine of a complex number. -Copyright (C) 2009 Philippe Th\'eveny, Paul Zimmermann +Copyright (C) 2009, 2010 Philippe Th\'eveny, Paul Zimmermann This file is part of the MPC Library. @@ -206,19 +206,22 @@ mpc_acos (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) inex_im = MPC_INEX_IM(inex); /* inex_im is in {-1, 0, 1} */ e2 = mpfr_get_exp (MPC_RE(z1)); mpfr_sub (MPC_RE(z1), pi_over_2, MPC_RE(z1), GMP_RNDN); - /* the error on x=Re(z1) is bounded by 1/2 ulp(x) + 2^(e1-p-1) + - 2^(e2-p-1) */ - e1 = e1 >= e2 ? e1 + 1 : e2 + 1; - /* the error on x is bounded by 1/2 ulp(x) + 2^(e1-p-1) */ - e1 -= mpfr_get_exp (MPC_RE(z1)); - /* the error on x is bounded by 1/2 ulp(x) [1 + 2^e1] */ - e1 = e1 <= 0 ? 0 : e1; - /* the error on x is bounded by 2^e1 * ulp(x) */ - mpfr_neg (MPC_IM(z1), MPC_IM(z1), GMP_RNDN); /* exact */ - inex_im = -inex_im; - if (mpfr_can_round (MPC_RE(z1), p - e1, GMP_RNDN, GMP_RNDZ, - p_re + (MPC_RND_RE(rnd) == GMP_RNDN))) - break; + if (!mpfr_zero_p (MPC_RE(z1))) + { + /* the error on x=Re(z1) is bounded by 1/2 ulp(x) + 2^(e1-p-1) + + 2^(e2-p-1) */ + e1 = e1 >= e2 ? e1 + 1 : e2 + 1; + /* the error on x is bounded by 1/2 ulp(x) + 2^(e1-p-1) */ + e1 -= mpfr_get_exp (MPC_RE(z1)); + /* the error on x is bounded by 1/2 ulp(x) [1 + 2^e1] */ + e1 = e1 <= 0 ? 0 : e1; + /* the error on x is bounded by 2^e1 * ulp(x) */ + mpfr_neg (MPC_IM(z1), MPC_IM(z1), GMP_RNDN); /* exact */ + inex_im = -inex_im; + if (mpfr_can_round (MPC_RE(z1), p - e1, GMP_RNDN, GMP_RNDZ, + p_re + (MPC_RND_RE(rnd) == GMP_RNDN))) + break; + } } inex = mpc_set (rop, z1, rnd); inex_re = MPC_INEX_RE(inex); |