summaryrefslogtreecommitdiff
path: root/src/pow_z.c
diff options
context:
space:
mode:
authorenge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2010-06-17 17:40:38 +0000
committerenge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4>2010-06-17 17:40:38 +0000
commit8f669fde281f3512784a5c53e3c8a1a87e5c283d (patch)
tree80af8ef84f59bcb51d8a51720b64edfc699035e5 /src/pow_z.c
parentcdae67dc9bf52fd118eff5ea82462fef46691143 (diff)
downloadmpc-8f669fde281f3512784a5c53e3c8a1a87e5c283d.tar.gz
unified computation of pow_ui and pow_si in a function pow_usi, thereby
applying binary exponentiation in the case of negative exponent git-svn-id: svn://scm.gforge.inria.fr/svn/mpc/trunk@788 211d60ee-9f03-0410-a15a-8952a2c7a4e4
Diffstat (limited to 'src/pow_z.c')
-rw-r--r--src/pow_z.c38
1 files changed, 21 insertions, 17 deletions
diff --git a/src/pow_z.c b/src/pow_z.c
index 9b769fe..dcc0530 100644
--- a/src/pow_z.c
+++ b/src/pow_z.c
@@ -1,6 +1,6 @@
/* mpc_pow_z -- Raise a complex number to an integer power.
-Copyright (C) 2009, 2010 Paul Zimmermann
+Copyright (C) 2009, 2010 Paul Zimmermann, Andreas Enge
This file is part of the MPC Library.
@@ -24,21 +24,25 @@ MA 02111-1307, USA. */
int
mpc_pow_z (mpc_ptr z, mpc_srcptr x, mpz_srcptr y, mpc_rnd_t rnd)
{
- mpc_t yy;
- int inex;
- size_t n = mpz_sizeinbase (y, 2);
-
- /* if y fits in an unsigned long or long, call the corresponding functions,
- which are supposed to be more efficient */
- if (mpz_fits_ulong_p (y))
- return mpc_pow_ui (z, x, mpz_get_ui (y), rnd);
- else if (mpz_fits_slong_p (y))
- return mpc_pow_si (z, x, mpz_get_si (y), rnd);
-
- mpc_init3 (yy, (n < MPFR_PREC_MIN) ? MPFR_PREC_MIN : n, MPFR_PREC_MIN);
- mpc_set_z (yy, y, MPC_RNDNN); /* exact */
- inex = mpc_pow (z, x, yy, rnd);
- mpc_clear (yy);
- return inex;
+ mpc_t yy;
+ int inex;
+ size_t n = mpz_sizeinbase (y, 2);
+
+ /* if y fits in an unsigned long or long, call the corresponding functions,
+ which are supposed to be more efficient */
+ if (mpz_cmp_ui (y, 0ul) >= 0) {
+ if (mpz_fits_ulong_p (y))
+ return mpc_pow_usi (z, x, mpz_get_ui (y), 1, rnd);
+ }
+ else {
+ if (mpz_fits_slong_p (y))
+ return mpc_pow_usi (z, x, (unsigned long) (-mpz_get_si (y)), -1, rnd);
+ }
+
+ mpc_init3 (yy, (n < MPFR_PREC_MIN) ? MPFR_PREC_MIN : n, MPFR_PREC_MIN);
+ mpc_set_z (yy, y, MPC_RNDNN); /* exact */
+ inex = mpc_pow (z, x, yy, rnd);
+ mpc_clear (yy);
+ return inex;
}