[Gmp-commit] /var/hg/gmp: 4 new changesets
mercurial at gmplib.org
mercurial at gmplib.org
Sat May 31 06:49:41 UTC 2014
details: /var/hg/gmp/rev/04ac0fcabf83
changeset: 16403:04ac0fcabf83
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Sat May 31 08:44:13 2014 +0200
description:
mpf/ui_sub.c: Remove buggy code, use a wrapper to mpf_sub.
details: /var/hg/gmp/rev/d0fb2b93b038
changeset: 16404:d0fb2b93b038
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Sat May 31 08:45:19 2014 +0200
description:
tests/mpf/t-sub.c: More corner cases and strict checking
details: /var/hg/gmp/rev/6953074c684a
changeset: 16405:6953074c684a
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Sat May 31 08:46:30 2014 +0200
description:
mpf/sub.c: Simplify using mpn_ primitives.
details: /var/hg/gmp/rev/7c865bee3023
changeset: 16406:7c865bee3023
user: Marco Bodrato <bodrato at mail.dm.unipi.it>
date: Sat May 31 08:49:35 2014 +0200
description:
ChangeLog
diffstat:
ChangeLog | 6 +
mpf/sub.c | 72 ++++----------
mpf/ui_sub.c | 264 +++++++++++++++++++++--------------------------------
tests/mpf/t-sub.c | 75 +++++++++------
4 files changed, 179 insertions(+), 238 deletions(-)
diffs (truncated from 717 to 300 lines):
diff -r 902a1b8de2e0 -r 7c865bee3023 ChangeLog
--- a/ChangeLog Thu May 29 14:25:22 2014 +0200
+++ b/ChangeLog Sat May 31 08:49:35 2014 +0200
@@ -1,3 +1,9 @@
+2014-05-31 Marco Bodrato <bodrato at mail.dm.unipi.it>
+
+ * mpf/ui_sub.c: Remove buggy code, use a wrapper to mpf_sub.
+ * tests/mpf/t-sub.c: More corner cases and strict checking.
+ * mpf/sub.c: Use more mpn_ primitives.
+
2014-05-29 Marc Glisse <marc.glisse at inria.fr>
* gmp-h.in: Include <limits.h>.
diff -r 902a1b8de2e0 -r 7c865bee3023 mpf/sub.c
--- a/mpf/sub.c Thu May 29 14:25:22 2014 +0200
+++ b/mpf/sub.c Sat May 31 08:49:35 2014 +0200
@@ -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 @@
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 @@
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 @@
goto cancellation;
}
}
- while (up[usize - 1] == vp[vsize - 1]);
- }
if (up[usize - 1] < vp[vsize - 1])
{
@@ -192,8 +188,7 @@
exp--;
}
}
-
- if (usize > prec - 1)
+ else if (usize > prec - 1)
{
up += usize - (prec - 1);
usize = prec - 1;
@@ -209,32 +204,18 @@
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 @@
{
/* 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 @@
tp[rsize] = 1;
rsize++;
exp++;
+ goto normalized;
}
goto normalize;
}
@@ -348,13 +327,10 @@
{
/* 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 @@
{
/* 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 @@
/* 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 @@
rsize--;
exp--;
}
+ normalized:
MPN_COPY (rp, tp, rsize);
}
diff -r 902a1b8de2e0 -r 7c865bee3023 mpf/ui_sub.c
--- a/mpf/ui_sub.c Thu May 29 14:25:22 2014 +0200
+++ b/mpf/ui_sub.c Sat May 31 08:49:35 2014 +0200
@@ -1,6 +1,6 @@
/* mpf_ui_sub -- Subtract a float from an unsigned long int.
-Copyright 1993-1996, 2001, 2002, 2005 Free Software Foundation, Inc.
+Copyright 1993-1996, 2001, 2002, 2005, 2014 Free Software Foundation, Inc.
This file is part of the GNU MP Library.
@@ -34,6 +34,23 @@
void
mpf_ui_sub (mpf_ptr r, unsigned long int u, mpf_srcptr v)
{
+#if 1
+ __mpf_struct uu;
+ mp_limb_t ul;
+
+ if (u == 0)
+ {
+ mpf_neg (r, v);
+ return;
+ }
+
+ ul = u;
+ uu._mp_size = 1;
+ uu._mp_d = &ul;
+ uu._mp_exp = 1;
+ mpf_sub (r, &uu, v);
+
+#else
mp_srcptr up, vp;
mp_ptr rp, tp;
mp_size_t usize, vsize, rsize;
@@ -69,89 +86,64 @@
return;
}
- TMP_MARK;
-
/* Signs are now known to be the same. */
-
+ ASSERT (vsize > 0);
ulimb = u;
/* Make U be the operand with the largest exponent. */
- if (1 < v->_mp_exp)
+ negate = 1 < v->_mp_exp;
+ prec = r->_mp_prec + negate;
+ rp = r->_mp_d;
+ if (negate)
{
- negate = 1;
- usize = ABS (vsize);
+ usize = vsize;
vsize = 1;
up = v->_mp_d;
vp = &ulimb;
- rp = r->_mp_d;
- prec = r->_mp_prec + 1;
uexp = v->_mp_exp;
ediff = uexp - 1;
+
+ /* If U extends beyond PREC, ignore the part that does. */
+ if (usize > prec)
+ {
+ up += usize - prec;
+ usize = prec;
+ }
+ ASSERT (ediff > 0);
}
else
{
- negate = 0;
- usize = 1;
- vsize = ABS (vsize);
- up = &ulimb;
vp = v->_mp_d;
- rp = r->_mp_d;
- prec = r->_mp_prec;
- uexp = 1;
ediff = 1 - v->_mp_exp;
- }
-
/* Ignore leading limbs in U and V that are equal. Doing
this helps increase the precision of the result. */
- if (ediff == 0)
- {
- /* This loop normally exits immediately. Optimize for that. */
- for (;;)
+ if (ediff == 0 && ulimb == vp[vsize - 1])
{
- usize--;
+ usize = 0;
vsize--;
- if (up[usize] != vp[vsize])
- break;
- uexp--;
- if (usize == 0)
- goto Lu0;
- if (vsize == 0)
- goto Lv0;
+ uexp = 0;
+ /* Note that V might now have leading zero limbs.
+ In that case we have to adjust uexp. */
+ for (;;)
+ {
+ if (vsize == 0) {
+ rsize = 0;
+ uexp = 0;
+ goto done;
+ }
+ if ( vp[vsize - 1] != 0)
+ break;
+ vsize--, uexp--;
+ }
}
- usize++;
More information about the gmp-commit
mailing list