summaryrefslogtreecommitdiff
path: root/src/div.c
diff options
context:
space:
mode:
authorzimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2009-08-26 10:09:36 +0000
committerzimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2009-08-26 10:09:36 +0000
commitb72fa1555ab1e2c5d0fb80276e32c3fb7d119564 (patch)
treea34b4c1ac286159e25378eba059aa114d0d3aeaf /src/div.c
parent0efbdf96af0314e6c0d0c555738a221cccab8d55 (diff)
downloadmpc-b72fa1555ab1e2c5d0fb80276e32c3fb7d119564.tar.gz
[div.c] fixed memory layout problem reported by Geoff Bailey on 13 Aug 2009
(http://lists.gforge.inria.fr/pipermail/mpc-discuss/2009-August/000491.html) git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@661 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'src/div.c')
-rw-r--r--src/div.c20
1 files changed, 11 insertions, 9 deletions
diff --git a/src/div.c b/src/div.c
index 1e346ef..95aa651 100644
--- a/src/div.c
+++ b/src/div.c
@@ -148,7 +148,7 @@ int
mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
{
int ok_re = 0, ok_im = 0;
- mpc_t res, c_conj;
+ mpc_t res, c_conj;
mpfr_t q;
mp_prec_t prec;
int inexact_prod, inexact_norm, inexact_re, inexact_im, loops = 0;
@@ -208,19 +208,21 @@ mpc_div (mpc_ptr a, mpc_srcptr b, mpc_srcptr c, mpc_rnd_t rnd)
int overlap = (a == b) || (a == c);
int imag_b = mpfr_zero_p (MPC_RE (b));
mpfr_t cloc;
+ mpc_t tmpa;
+ mpc_ptr dest = (overlap) ? tmpa : a;
if (overlap)
- mpc_init3 (res, MPFR_PREC (MPC_RE (a)), MPFR_PREC (MPC_IM (a)));
- else
- res [0] = *a;
- cloc [0] = MPC_IM (c) [0];
- inexact_re = mpfr_div (MPC_RE(res), MPC_IM(b), cloc, MPC_RND_RE(rnd));
+ mpc_init3 (tmpa, MPFR_PREC (MPC_RE (a)), MPFR_PREC (MPC_IM (a)));
+ cloc[0] = MPC_IM(c)[0]; /* copies mpfr struct IM(c) into cloc */
+ inexact_re = mpfr_div (MPC_RE(dest), MPC_IM(b), cloc, MPC_RND_RE(rnd));
mpfr_neg (cloc, cloc, GMP_RNDN);
/* changes the sign only in cloc, not in c; no need to correct later */
- inexact_im = mpfr_div (MPC_IM(res), MPC_RE(b), cloc, MPC_RND_IM(rnd));
+ inexact_im = mpfr_div (MPC_IM(dest), MPC_RE(b), cloc, MPC_RND_IM(rnd));
if (overlap)
- mpc_clear (a);
- a [0] = res [0];
+ {
+ mpc_set (a, tmpa, MPC_RNDNN); /* exact */
+ mpc_clear (tmpa);
+ }
/* correct signs of zeroes if necessary, which does not affect the
inexact flags */