summaryrefslogtreecommitdiff
path: root/src/sqr.c
diff options
context:
space:
mode:
authorthevenyp <thevenyp@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2008-10-21 12:51:45 +0000
committerthevenyp <thevenyp@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2008-10-21 12:51:45 +0000
commitbc62c194d13717100b90069bce89117caee30a87 (patch)
tree472f7f6b785b89595ff231cbe6f88361304d67b2 /src/sqr.c
parent9debaa88634b219e3eea98c483fdc5bdc383c320 (diff)
downloadmpc-bc62c194d13717100b90069bce89117caee30a87.tar.gz
src/sqr.c: Fix bug when reusing parameter and parameter value is pure real or pure imaginary but with a negative sign (-0).
tests/tsqr.c: add reuse bug found by Paul Zimmermann. git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@264 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'src/sqr.c')
-rw-r--r--src/sqr.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/src/sqr.c b/src/sqr.c
index c94f77a..30b0219 100644
--- a/src/sqr.c
+++ b/src/sqr.c
@@ -1,6 +1,6 @@
/* mpc_sqr -- Square a complex number.
-Copyright (C) 2002, 2005, 2008 Andreas Enge, Paul Zimmermann
+Copyright (C) 2002, 2005, 2008 Andreas Enge, Paul Zimmermann, Philippe Th\'eveny
This file is part of the MPC Library.
@@ -76,19 +76,21 @@ mpc_sqr (mpc_ptr rop, mpc_srcptr op, mpc_rnd_t rnd)
/* first check for real resp. purely imaginary number */
if (MPFR_IS_ZERO (MPC_IM(op)))
{
+ int same_sign = mpfr_signbit (MPC_RE (op)) == mpfr_signbit (MPC_IM (op));
inex_re = mpfr_sqr (MPC_RE(rop), MPC_RE(op), MPC_RND_RE(rnd));
inex_im = mpfr_set_ui (MPC_IM(rop), 0ul, GMP_RNDN);
- if (MPFR_SIGN (MPC_RE (op)) * MPFR_SIGN (MPC_IM (op)) < 0)
- MPFR_CHANGE_SIGN (MPC_IM (rop));
+ if (!same_sign)
+ mpc_conj (rop, rop, MPC_RNDNN);
return MPC_INEX(inex_re, inex_im);
}
if (MPFR_IS_ZERO (MPC_RE(op)))
{
+ int same_sign = mpfr_signbit (MPC_RE (op)) == mpfr_signbit (MPC_IM (op));
inex_re = -mpfr_sqr (MPC_RE(rop), MPC_IM(op), INV_RND (MPC_RND_RE(rnd)));
mpfr_neg (MPC_RE(rop), MPC_RE(rop), GMP_RNDN);
inex_im = mpfr_set_ui (MPC_IM(rop), 0ul, GMP_RNDN);
- if (MPFR_SIGN (MPC_RE (op)) * MPFR_SIGN (MPC_IM (op)) < 0)
- MPFR_CHANGE_SIGN (MPC_IM (rop));
+ if (!same_sign)
+ mpc_conj (rop, rop, MPC_RNDNN);
return MPC_INEX(inex_re, inex_im);
}
/* If the real and imaginary part of the argument have rop very different */