summaryrefslogtreecommitdiff
path: root/src/atan.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2010-08-31 12:30:40 +0000
committerzimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2010-08-31 12:30:40 +0000
commitda7ecc6ae4f8836ca507e8c7de2e56abc372c5fc (patch)
treefac5da9dbfd3e46f02ebd1bdca9eaef9c386b2b5 /src/atan.c
parent8a098efd6bc329d4474bb419d704fb63d319f875 (diff)
downloadmpc-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.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/src/atan.c b/src/atan.c
index b393fc2..feb8c47 100644
--- a/src/atan.c
+++ b/src/atan.c
@@ -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);