[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