diff options
author | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2014-06-25 08:05:09 +0000 |
---|---|---|
committer | zimmerma <zimmerma@280ebfd0-de03-0410-8827-d642c229c3f4> | 2014-06-25 08:05:09 +0000 |
commit | 6d9eb54d507684e38c2baa84bbd03611795ce2db (patch) | |
tree | 751ddb999f32bac0a56aba8b70f3cb4bab96407b /src | |
parent | 642b7ce46f1e5899f1b92cbee8437de4ab525872 (diff) | |
download | mpfr-6d9eb54d507684e38c2baa84bbd03611795ce2db.tar.gz |
speedup of mpfr_div when divisor has one limb
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9086 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'src')
-rw-r--r-- | src/div.c | 22 |
1 files changed, 22 insertions, 0 deletions
@@ -240,6 +240,28 @@ mpfr_div (mpfr_ptr q, mpfr_srcptr u, mpfr_srcptr v, mpfr_rnd_t rnd_mode) * * **************************************************************************/ + /* when the divisor has one limb, we can use mpfr_div_ui, which should be + faster, assuming there is no intermediate overflow or underflow. + The divisor interpreted as an integer satisfies + 2^(GMP_NUMB_BITS-1) <= vm < 2^GMP_NUMB_BITS, thus the quotient + satisfies 2^(EXP(u)-1-GMP_NUMB_BITS) < u/vm < 2^(EXP(u)-GMP_NUMB_BITS+1) + and its exponent is either EXP(u)-GMP_NUMB_BITS or one more. */ + if (vsize <= 1 && __gmpfr_emin <= MPFR_EXP(u) - GMP_NUMB_BITS + && MPFR_EXP(u) - GMP_NUMB_BITS + 1 <= __gmpfr_emax) + { + mpfr_exp_t exp_v = MPFR_EXP(v); /* save it in case q=v */ + if (MPFR_SIGN(v) > 0) + inex = mpfr_div_ui (q, u, vp[0], rnd_mode); + else + { + inex = -mpfr_div_ui (q, u, vp[0], MPFR_INVERT_RND(rnd_mode)); + MPFR_CHANGE_SIGN(q); + } + /* q did not under/overflow */ + MPFR_EXP(q) -= exp_v - GMP_NUMB_BITS; + return mpfr_check_range (q, inex, rnd_mode); + } + MPFR_TMP_MARK(marker); /* set sign */ |