summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorzimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2009-06-18 14:08:20 +0000
committerzimmerma <zimmerma@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2009-06-18 14:08:20 +0000
commit8855b10f8dbae2a03d2c1c2eb07ae57a274158d8 (patch)
tree52e6dbf8161ccc90db378dcd964ad5a343a4287d
parentb9c268e1836686efc6f91d0a14dda12693d6785a (diff)
downloadmpc-8855b10f8dbae2a03d2c1c2eb07ae57a274158d8.tar.gz
[pow.c] fixed two bugs: one where the exponent was wrong, and one case where
it was looping due to undetected zero real part git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@609 211d60ee-9f03-0410-a15a-8952a2c7a4e4
-rw-r--r--src/pow.c35
-rw-r--r--tests/pow.dat2
2 files changed, 22 insertions, 15 deletions
diff --git a/src/pow.c b/src/pow.c
index caa6f0d..a337763 100644
--- a/src/pow.c
+++ b/src/pow.c
@@ -231,7 +231,7 @@ mpc_pow_exact (mpc_ptr z, mpc_srcptr x, mpfr_srcptr y, mpc_rnd_t rnd)
}
/* replace (c,d) by (c/(c^2-d^2), -d/(c^2-d^2)) */
mpz_neg (d, d);
- ec -= t;
+ ec = -ec - t;
}
mpz_neg (my, my);
}
@@ -414,25 +414,30 @@ mpc_pow (mpc_ptr z, mpc_srcptr x, mpc_srcptr y, mpc_rnd_t rnd)
if (mpfr_cmp_si (MPC_RE(x), -1) == 0 && mpfr_integer_p (MPC_RE(y)))
z_real = 1;
- /* x^y is imaginary when:
+ /* for x real, x^y is imaginary when:
(a) x is negative and y is half-an-integer
- (b) x = -1 and Re(y) is half-an-integer */
+ (b) x = -1 and Re(y) is half-an-integer
+ */
if (mpfr_cmp_ui (MPC_RE(x), 0) < 0 && is_odd (MPC_RE(y), 1) &&
(y_real || mpfr_cmp_si (MPC_RE(x), -1) == 0))
z_imag = 1;
}
-
- /* I^(t*I) and (-I)^(t*I) are real for t real,
- I^(n+t*I) and (-I)^(n+t*I) are real for n even and t real, and
- I^(n+t*I) and (-I)^(n+t*I) are imaginary for n odd and t real */
- if ((mpc_cmp_si_si (x, 0, 1) == 0 || mpc_cmp_si_si (x, 0, -1) == 0) &&
- mpfr_integer_p (MPC_RE(y)))
- { /* x is I or -I, and Re(y) is an integer */
- if (is_odd (MPC_RE(y), 0))
- z_imag = 1; /* Re(y) odd: z is imaginary */
- else
- z_real = 1; /* Re(y) even: z is real */
- }
+ else /* x non real */
+ /* I^(t*I) and (-I)^(t*I) are real for t real,
+ I^(n+t*I) and (-I)^(n+t*I) are real for n even and t real, and
+ I^(n+t*I) and (-I)^(n+t*I) are imaginary for n odd and t real */
+ if ((mpc_cmp_si_si (x, 0, 1) == 0 || mpc_cmp_si_si (x, 0, -1) == 0) &&
+ mpfr_integer_p (MPC_RE(y)))
+ { /* x is I or -I, and Re(y) is an integer */
+ if (is_odd (MPC_RE(y), 0))
+ z_imag = 1; /* Re(y) odd: z is imaginary */
+ else
+ z_real = 1; /* Re(y) even: z is real */
+ }
+ else /* x^y is imaginary x is imaginary and y = -1 */
+ if (mpfr_cmp_ui (MPC_RE(x), 0) == 0 && y_real &&
+ mpfr_cmp_si (MPC_RE(y), -1) == 0)
+ z_imag = 1;
/* first bound |Re(y log(x))|, |Im(y log(x)| < 2^q */
mpc_init2 (t, 64);
diff --git a/tests/pow.dat b/tests/pow.dat
index 857d418..1f8698b 100644
--- a/tests/pow.dat
+++ b/tests/pow.dat
@@ -174,3 +174,5 @@
0 0 2 -0x1p-18 2 0x1p-18 2 -0x1p14 2 0 3 -0x5p-2 3 0 N N
# e=2 n=5
0 0 2 -0x1p-13 2 0x1p-13 2 -0x1p10 2 0 3 -0x5p-2 3 0 N N
+0 0 2 +0 2 -2 2 +0 2 0x1p-1 2 -1 2 -0 N N
+0 - 2 +0 3 -5 2 +0 53 0xCCCCCCCCCCCCDp-54 2 -1 2 -0 N N