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/atan.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/atan.c')
-rw-r--r-- | src/atan.c | 35 |
1 files changed, 20 insertions, 15 deletions
@@ -1,6 +1,6 @@ /* mpc_atan -- arctangent 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. @@ -331,21 +331,26 @@ mpc_atan (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd) mpfr_sub (y, a, b, GMP_RNDU); - expo = MPC_MAX (mpfr_get_exp (a), mpfr_get_exp (b)); - expo = expo - mpfr_get_exp (y) + 1; - err = 3 - mpfr_get_exp (y); - /* error(j) <= [1 + 2^expo + 7*2^err] ulp(j) */ - if (expo <= err) /* error(j) <= [1 + 2^{err+1}] ulp(j) */ - err = (err < 0) ? 1 : err + 2; - else - err = (expo < 0) ? 1 : expo + 2; - - mpfr_div_2ui (y, y, 2, GMP_RNDN); if (mpfr_zero_p (y)) - err = 2; /* underflow */ - - ok = mpfr_can_round (y, p - err, GMP_RNDU, GMP_RNDD, - prec + (MPC_RND_IM (rnd) == GMP_RNDN)); + ok = 0; + else + { + expo = MPC_MAX (mpfr_get_exp (a), mpfr_get_exp (b)); + expo = expo - mpfr_get_exp (y) + 1; + err = 3 - mpfr_get_exp (y); + /* error(j) <= [1 + 2^expo + 7*2^err] ulp(j) */ + if (expo <= err) /* error(j) <= [1 + 2^{err+1}] ulp(j) */ + err = (err < 0) ? 1 : err + 2; + else + err = (expo < 0) ? 1 : expo + 2; + + mpfr_div_2ui (y, y, 2, GMP_RNDN); + if (mpfr_zero_p (y)) + err = 2; /* underflow */ + + ok = mpfr_can_round (y, p - err, GMP_RNDU, GMP_RNDD, + prec + (MPC_RND_IM (rnd) == GMP_RNDN)); + } } while (ok == 0); inex = mpc_set_fr_fr (rop, x, y, rnd); |