summaryrefslogtreecommitdiff
path: root/mul.c
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2003-11-19 10:01:34 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2003-11-19 10:01:34 +0000
commit185dd575ae55b859e07c0ef7765cc0afd258079a (patch)
tree1921ab7720919687df9d25c74fe543555079eff1 /mul.c
parentafa09509c72f5158b2e2f8823f999d0a370f869d (diff)
downloadmpfr-185dd575ae55b859e07c0ef7765cc0afd258079a.tar.gz
Optimization of mpfr_mul.
Tiny optimization of mpfr_pow (The case y=0 has been put inside the MPFR_ARE_SINGULAR block). Tiny optimisation of mpfr_set_ui. git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@2554 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'mul.c')
-rw-r--r--mul.c34
1 files changed, 16 insertions, 18 deletions
diff --git a/mul.c b/mul.c
index 10d4ca735..a40283774 100644
--- a/mul.c
+++ b/mul.c
@@ -29,7 +29,7 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
{
int sign_product, cc, inexact;
mp_exp_t ax, bx, cx;
- mp_limb_t *ap, *bp, *cp, *tmp;
+ mp_limb_t *tmp;
mp_limb_t b1;
mp_prec_t aq, bq, cq;
mp_size_t an, bn, cn, tn, k;
@@ -103,22 +103,21 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
sign_product);
*/
- ap = MPFR_MANT(a);
- bp = MPFR_MANT(b);
- cp = MPFR_MANT(c);
-
aq = MPFR_PREC(a);
bq = MPFR_PREC(b);
cq = MPFR_PREC(c);
+
+ /* Set the sign: can't be done before to let the multiply done */
+ MPFR_SET_SIGN(a, sign_product);
MPFR_ASSERTD(bq+cq > bq); /* PREC_MAX is /2 so no integer overflow */
- an = (aq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of a */
- bn = (bq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of b */
- cn = (cq-1)/BITS_PER_MP_LIMB + 1; /* number of significant limbs of c */
+ an = (aq+BITS_PER_MP_LIMB-1)/BITS_PER_MP_LIMB; /* number of limbs of a */
+ bn = (bq+BITS_PER_MP_LIMB-1)/BITS_PER_MP_LIMB; /* number of limbs of b */
+ cn = (cq+BITS_PER_MP_LIMB-1)/BITS_PER_MP_LIMB; /* number of limbs of c */
k = bn + cn; /* effective nb of limbs used by b*c (= tn or tn+1) below */
-
- tn = (bq + cq - 1) / BITS_PER_MP_LIMB + 1; /* <= k, thus no int overflow */
+ tn = (bq + cq + BITS_PER_MP_LIMB - 1) / BITS_PER_MP_LIMB;
+ /* <= k, thus no int overflow */
MPFR_ASSERTD(tn <= k);
/* Check for no size_t overflow*/
@@ -127,20 +126,21 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
tmp = (mp_limb_t *) TMP_ALLOC((size_t) k * BYTES_PER_MP_LIMB);
/* multiplies two mantissa in temporary allocated space */
- b1 = (MPFR_LIKELY(bn >= cn)) ? mpn_mul (tmp, bp, bn, cp, cn)
- : mpn_mul (tmp, cp, cn, bp, bn);
+ b1 = (MPFR_LIKELY(bn >= cn)) ?
+ mpn_mul (tmp, MPFR_MANT(b), bn, MPFR_MANT(c), cn)
+ : mpn_mul (tmp, MPFR_MANT(c), cn, MPFR_MANT(b), bn);
/* now tmp[0]..tmp[k-1] contains the product of both mantissa,
with tmp[k-1]>=2^(BITS_PER_MP_LIMB-2) */
b1 >>= BITS_PER_MP_LIMB - 1; /* msb from the product */
tmp += k - tn;
- if (b1 == 0)
+ if (MPFR_UNLIKELY(b1 == 0))
mpn_lshift (tmp, tmp, tn, 1);
- cc = mpfr_round_raw (ap, tmp, bq + cq, MPFR_IS_NEG_SIGN(sign_product), aq,
- rnd_mode, &inexact);
+ cc = mpfr_round_raw (MPFR_MANT(a), tmp, bq + cq,
+ MPFR_IS_NEG_SIGN(sign_product), aq, rnd_mode, &inexact);
if (MPFR_UNLIKELY(cc)) /* cc = 1 ==> result is a power of two */
- ap[an-1] = MPFR_LIMB_HIGHBIT;
+ MPFR_MANT(a)[an-1] = MPFR_LIMB_HIGHBIT;
TMP_FREE(marker);
@@ -161,7 +161,5 @@ mpfr_mul (mpfr_ptr a, mpfr_srcptr b, mpfr_srcptr c, mp_rnd_t rnd_mode)
}
MPFR_SET_EXP (a, ax);
- MPFR_SET_SIGN(a, sign_product);
-
return inexact;
}