diff options
author | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2010-06-17 17:40:38 +0000 |
---|---|---|
committer | enge <enge@211d60ee-9f03-0410-a15a-8952a2c7a4e4> | 2010-06-17 17:40:38 +0000 |
commit | 8f669fde281f3512784a5c53e3c8a1a87e5c283d (patch) | |
tree | 80af8ef84f59bcb51d8a51720b64edfc699035e5 /src/pow_z.c | |
parent | cdae67dc9bf52fd118eff5ea82462fef46691143 (diff) | |
download | mpc-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.c | 38 |
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; } |