summaryrefslogtreecommitdiff
path: root/mpf
diff options
context:
space:
mode:
authorMarco Bodrato <bodrato@mail.dm.unipi.it>2014-05-31 08:46:30 +0200
committerMarco Bodrato <bodrato@mail.dm.unipi.it>2014-05-31 08:46:30 +0200
commitea292b1c9b351bacc402ec349810bfa0c22d1a59 (patch)
treea514c878f58ec92f47f54b35d653eeb43b346467 /mpf
parenta4f3a3016f32305a3ba605831382ff893dc17f87 (diff)
downloadgmp-ea292b1c9b351bacc402ec349810bfa0c22d1a59.tar.gz
mpf/sub.c: Simplify using mpn_ primitives.
Diffstat (limited to 'mpf')
-rw-r--r--mpf/sub.c72
1 files changed, 23 insertions, 49 deletions
diff --git a/mpf/sub.c b/mpf/sub.c
index 3aaf19279..379f1bdef 100644
--- a/mpf/sub.c
+++ b/mpf/sub.c
@@ -1,6 +1,6 @@
/* mpf_sub -- Subtract two floats.
-Copyright 1993-1996, 1999-2002, 2004, 2005, 2011 Free Software Foundation, Inc.
+Copyright 1993-1996, 1999-2002, 2004, 2005, 2011, 2014 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -92,7 +92,7 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
rp = r->_mp_d;
prec = r->_mp_prec + 1;
exp = u->_mp_exp;
- ediff = u->_mp_exp - v->_mp_exp;
+ ediff = exp - v->_mp_exp;
/* If ediff is 0 or 1, we might have a situation where the operands are
extremely close. We need to scan the operands from the most significant
@@ -102,10 +102,8 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
if (ediff == 0)
{
/* Skip leading limbs in U and V that are equal. */
- if (up[usize - 1] == vp[vsize - 1])
- {
/* This loop normally exits immediately. Optimize for that. */
- do
+ while (up[usize - 1] == vp[vsize - 1])
{
usize--;
vsize--;
@@ -138,8 +136,6 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
goto cancellation;
}
}
- while (up[usize - 1] == vp[vsize - 1]);
- }
if (up[usize - 1] < vp[vsize - 1])
{
@@ -192,8 +188,7 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
exp--;
}
}
-
- if (usize > prec - 1)
+ else if (usize > prec - 1)
{
up += usize - (prec - 1);
usize = prec - 1;
@@ -209,32 +204,18 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
mp_limb_t cy_limb;
if (vsize == 0)
{
- mp_size_t size, i;
- size = usize;
- for (i = 0; i < size; i++)
- tp[i] = up[i];
- tp[size] = 1;
- rsize = size + 1;
+ MPN_COPY (tp, up, usize);
+ tp[usize] = 1;
+ rsize = usize + 1;
exp++;
- goto normalize;
+ goto normalized;
}
if (usize == 0)
{
- mp_size_t size, i;
- size = vsize;
- for (i = 0; i < size; i++)
- tp[i] = ~vp[i] & GMP_NUMB_MASK;
- cy_limb = 1 - mpn_add_1 (tp, tp, vsize, (mp_limb_t) 1);
+ cy_limb = mpn_neg (tp, vp, vsize);
rsize = vsize;
- if (cy_limb == 0)
- {
- tp[rsize] = 1;
- rsize++;
- exp++;
- }
- goto normalize;
}
- if (usize >= vsize)
+ else if (usize >= vsize)
{
/* uuuu */
/* vv */
@@ -248,13 +229,10 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
{
/* uuuu */
/* vvvvvvv */
- mp_size_t size, i;
+ mp_size_t size;
size = vsize - usize;
- for (i = 0; i < size; i++)
- tp[i] = ~vp[i] & GMP_NUMB_MASK;
- cy_limb = mpn_sub_n (tp + size, up, vp + size, usize);
- cy_limb+= mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
- cy_limb-= mpn_add_1 (tp, tp, vsize, (mp_limb_t) 1);
+ cy_limb = mpn_neg (tp, vp, size);
+ cy_limb = mpn_sub_nc (tp + size, up, vp + size, usize, cy_limb);
rsize = vsize;
}
if (cy_limb == 0)
@@ -262,6 +240,7 @@ mpf_sub (mpf_ptr r, mpf_srcptr u, mpf_srcptr v)
tp[rsize] = 1;
rsize++;
exp++;
+ goto normalized;
}
goto normalize;
}
@@ -348,13 +327,10 @@ general_case:
{
/* uuuu */
/* vvvvvvv */
- mp_size_t size, i;
+ mp_size_t size;
size = vsize - usize;
- tp[0] = -vp[0] & GMP_NUMB_MASK;
- for (i = 1; i < size; i++)
- tp[i] = ~vp[i] & GMP_NUMB_MASK;
- mpn_sub_n (tp + size, up, vp + size, usize);
- mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ ASSERT_CARRY (mpn_neg (tp, vp, size));
+ mpn_sub_nc (tp + size, up, vp + size, usize, CNST_LIMB (1));
rsize = vsize;
}
}
@@ -374,13 +350,12 @@ general_case:
{
/* uuuu */
/* vvvvv */
- mp_size_t size, i;
+ mp_size_t size;
size = vsize + ediff - usize;
- tp[0] = -vp[0] & GMP_NUMB_MASK;
- for (i = 1; i < size; i++)
- tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ ASSERT_CARRY (mpn_neg (tp, vp, size));
mpn_sub (tp + size, up, usize, vp + size, usize - ediff);
- mpn_sub_1 (tp + size, tp + size, usize, (mp_limb_t) 1);
+ /* Should we use sub_nc then sub_1? */
+ MPN_DECR_U (tp + size, usize, CNST_LIMB (1));
rsize = vsize + ediff;
}
}
@@ -391,9 +366,7 @@ general_case:
/* vv */
mp_size_t size, i;
size = vsize + ediff - usize;
- tp[0] = -vp[0] & GMP_NUMB_MASK;
- for (i = 1; i < vsize; i++)
- tp[i] = ~vp[i] & GMP_NUMB_MASK;
+ ASSERT_CARRY (mpn_neg (tp, vp, vsize));
for (i = vsize; i < size; i++)
tp[i] = GMP_NUMB_MAX;
mpn_sub_1 (tp + size, up, usize, (mp_limb_t) 1);
@@ -407,6 +380,7 @@ general_case:
rsize--;
exp--;
}
+ normalized:
MPN_COPY (rp, tp, rsize);
}