[Gmp-commit] /var/hg/gmp: 2 new changesets

mercurial at gmplib.org mercurial at gmplib.org
Tue Jan 8 21:43:27 CET 2013


details:   /var/hg/gmp/rev/0a3077c46f72
changeset: 15245:0a3077c46f72
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Tue Jan 08 21:32:46 2013 +0100
description:
mini-gmp: Fixed mpz_export to not generate leading zero words.

details:   /var/hg/gmp/rev/bf2c415056f1
changeset: 15246:bf2c415056f1
user:      Niels M?ller <nisse at lysator.liu.se>
date:      Tue Jan 08 21:42:57 2013 +0100
description:
mini-gmp: Test program for mpz_import and mpz_export.

diffstat:

 ChangeLog                    |   15 +++++
 mini-gmp/mini-gmp.c          |   47 +++++++++++-------
 mini-gmp/tests/Makefile      |    2 +-
 mini-gmp/tests/hex-random.c  |   15 +++++
 mini-gmp/tests/hex-random.h  |    4 +
 mini-gmp/tests/mini-random.c |   10 +++
 mini-gmp/tests/mini-random.h |    4 +
 mini-gmp/tests/t-import.c    |  109 +++++++++++++++++++++++++++++++++++++++++++
 8 files changed, 186 insertions(+), 20 deletions(-)

diffs (286 lines):

diff -r dae7c695e563 -r bf2c415056f1 ChangeLog
--- a/ChangeLog	Tue Jan 08 18:13:28 2013 +0100
+++ b/ChangeLog	Tue Jan 08 21:42:57 2013 +0100
@@ -1,3 +1,18 @@
+2013-01-08  Niels Möller  <nisse at lysator.liu.se>
+
+	* mini-gmp/tests/t-import.c: New test program, testing both
+	mpz_import and mpz_export.
+	* mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-import.
+
+	* mini-gmp/tests/mini-random.c (mini_rrandomb_export): New
+	function.
+	* mini-gmp/tests/mini-random.h: Declare it.
+	* mini-gmp/tests/hex-random.c (hex_rrandomb_export): New function.
+	* mini-gmp/tests/hex-random.h: Declare it.
+
+	* mini-gmp/mini-gmp.c (mpz_export): Compute accurate word count up
+	front, to avoid generating any high zero words.
+
 2013-01-07 Marco Bodrato <bodrato at mail.dm.unipi.it>
 
 	* mini-gmp/README: Document base limitation for conversions.
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c	Tue Jan 08 18:13:28 2013 +0100
+++ b/mini-gmp/mini-gmp.c	Tue Jan 08 21:42:57 2013 +0100
@@ -4101,9 +4101,19 @@
   assert (size > 0);
 
   un = GMP_ABS (u->_mp_size);
-  count = (un * sizeof (mp_limb_t) + size - 1) / size;
-
-  if (un) {
+  if (un == 0)
+    {
+      *countp = 0;
+      return r;
+    }
+
+  /* Count bytes in top limb. */
+  for (limb = u->_mp_d[un-1], k = 0; limb > 0; k++, limb >>= CHAR_BIT)
+    ;
+
+  assert (k > 0);
+
+  count = (k + (un-1) * sizeof (mp_limb_t) + size - 1) / size;
 
   if (!r)
     r = gmp_xalloc (count * size);
@@ -4128,24 +4138,23 @@
     p += (size - 1);
 
   for (bytes = 0, i = 0, k = 0; k < count; k++, p += word_step)
-    {
-      size_t j;
-      for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
-	{
-	  if (bytes == 0)
-	    {
-	      if (i < un)
-		limb = u->_mp_d[i++];
-	      bytes = sizeof (mp_limb_t);
-	    }
-	  *p = limb;
-	  limb >>= CHAR_BIT;
-	  bytes--;
-	}
-    }
+      {
+	size_t j;
+	for (j = 0; j < size; j++, p -= (ptrdiff_t) endian)
+	  {
+	    if (bytes == 0)
+	      {
+		if (i < un)
+		  limb = u->_mp_d[i++];
+		bytes = sizeof (mp_limb_t);
+	      }
+	    *p = limb;
+	    limb >>= CHAR_BIT;
+	    bytes--;
+	  }
+      }
   assert (i == un);
   assert (k == count);
-  }
 
   if (countp)
     *countp = count;
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/tests/Makefile
--- a/mini-gmp/tests/Makefile	Tue Jan 08 18:13:28 2013 +0100
+++ b/mini-gmp/tests/Makefile	Tue Jan 08 21:42:57 2013 +0100
@@ -28,7 +28,7 @@
 LIBS = -lgmp -lm -lmcheck
 
 CHECK_PROGRAMS = t-add t-sub t-mul t-invert t-div t-div_2exp \
-	t-double t-gcd t-lcm \
+	t-double t-gcd t-lcm t-import \
 	t-sqrt t-root t-powm t-logops t-bitops t-scan t-str \
 	t-reuse
 
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/tests/hex-random.c
--- a/mini-gmp/tests/hex-random.c	Tue Jan 08 18:13:28 2013 +0100
+++ b/mini-gmp/tests/hex-random.c	Tue Jan 08 21:42:57 2013 +0100
@@ -80,6 +80,21 @@
   return res;
 }
 
+char *
+hex_rrandomb_export (void *dst, size_t *countp,
+		     int order, size_t size, int endian, unsigned long bits)
+{
+  char *res;
+  mpz_t x;
+  mpz_init (x);
+  mpz_rrandomb (x, state, bits);
+  gmp_asprintf (&res, "%Zx", x);
+  mpz_export (dst, countp, order, size, endian, 0, x);
+  mpz_clear (x);
+  return res;
+  
+}
+  
 void
 hex_random_op (enum hex_random_op op,  unsigned long maxbits,
 	       char **ap, char **bp, char **rp)
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/tests/hex-random.h
--- a/mini-gmp/tests/hex-random.h	Tue Jan 08 18:13:28 2013 +0100
+++ b/mini-gmp/tests/hex-random.h	Tue Jan 08 21:42:57 2013 +0100
@@ -31,6 +31,10 @@
 void hex_random_init (void);
 char *hex_urandomb (unsigned long bits);
 char *hex_rrandomb (unsigned long bits);
+char *hex_rrandomb_export (void *dst, size_t *countp,
+			   int order, size_t size, int endian,
+			   unsigned long bits);
+
 void hex_random_op (enum hex_random_op op,  unsigned long maxbits,
 		    char **ap, char **bp, char **rp);
 void hex_random_op4 (enum hex_random_op op,  unsigned long maxbits,
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/tests/mini-random.c
--- a/mini-gmp/tests/mini-random.c	Tue Jan 08 18:13:28 2013 +0100
+++ b/mini-gmp/tests/mini-random.c	Tue Jan 08 21:42:57 2013 +0100
@@ -51,6 +51,16 @@
 }
 
 void
+mini_rrandomb_export (mpz_t r, void *dst, size_t *countp,
+		      int order, size_t size, int endian, unsigned long bits)
+{
+  char *s;
+  s = hex_rrandomb_export (dst, countp, order, size, endian, bits);
+  set_str (r, s);
+  free (s);
+}
+
+void
 mini_random_op (enum hex_random_op op, unsigned long maxbits,
 		mpz_t a, mpz_t b, mpz_t r)
 {
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/tests/mini-random.h
--- a/mini-gmp/tests/mini-random.h	Tue Jan 08 18:13:28 2013 +0100
+++ b/mini-gmp/tests/mini-random.h	Tue Jan 08 21:42:57 2013 +0100
@@ -22,6 +22,10 @@
 
 void mini_urandomb (mpz_t, unsigned long);
 void mini_rrandomb (mpz_t, unsigned long);
+void mini_rrandomb_export (mpz_t r, void *dst, size_t *countp,
+			   int order, size_t size, int endian,
+			   unsigned long bits);
+
 void mini_random_op (enum hex_random_op,  unsigned long, mpz_t, mpz_t, mpz_t);
 void mini_random_op4 (enum hex_random_op, unsigned long, mpz_t, mpz_t, mpz_t, mpz_t);
 void mini_random_scan_op (enum hex_random_op, unsigned long, mpz_t, mp_bitcnt_t *, mp_bitcnt_t *);
diff -r dae7c695e563 -r bf2c415056f1 mini-gmp/tests/t-import.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mini-gmp/tests/t-import.c	Tue Jan 08 21:42:57 2013 +0100
@@ -0,0 +1,109 @@
+/*
+
+Copyright 2013, Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library test suite.
+
+The GNU MP Library test suite is free software; you can redistribute it
+and/or modify it under the terms of the GNU General Public License as
+published by the Free Software Foundation; either version 3 of the License,
+or (at your option) any later version.
+
+The GNU MP Library test suite is distributed in the hope that it will be
+useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+Public License for more details.
+
+You should have received a copy of the GNU General Public License along with
+the GNU MP Library test suite.  If not, see http://www.gnu.org/licenses/.  */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "mini-random.h"
+
+#define MAX_WORDS 20
+#define MAX_WORD_SIZE 10
+
+static void
+dump (const char *label, const mpz_t x)
+{
+  char *buf = mpz_get_str (NULL, 16, x);
+  fprintf (stderr, "%s: %s\n", label, buf);
+  free (buf);
+}
+
+static void
+dump_bytes (const char *label, const unsigned char *s, size_t n)
+{
+  size_t i;
+  fprintf (stderr, "%s:", label);
+  for (i = 0; i < n; i++)
+    {
+      if (i && (i % 16) == 0)
+	fprintf (stderr, "\n");
+      fprintf (stderr, " %02x", s[i]);
+    }
+  fprintf (stderr, "\n");  
+}
+
+/* Tests both mpz_import and mpz_export. */
+int
+main (int argc, char **argv)
+{
+  unsigned char input[MAX_WORDS * MAX_WORD_SIZE];
+  unsigned char output[MAX_WORDS * MAX_WORD_SIZE + 2];
+  size_t count, in_count, out_count, size;
+  int endian, order;
+  
+  mpz_t a, res;
+
+  hex_random_init ();
+
+  mpz_init (a);
+  mpz_init (res);
+
+  for (size = 1; size <= MAX_WORD_SIZE; size++)
+    for (count = 1; count <= MAX_WORDS; count++)
+      for (endian = -1; endian <= 1; endian++)
+	for (order = -1; order <= 1; order += 2)
+	  {
+	    mini_rrandomb_export (a, input, &in_count,
+				  order, size, endian, size*count * 8);
+	    mpz_import (res, in_count, order, size, endian, 0, input);
+	    if (mpz_cmp (a, res))
+	      {
+		fprintf (stderr, "mpz_import failed:\n"
+			 "in_count %d, out_count %d, endian = %d, order = %d\n",
+			 in_count, out_count, endian, order);
+		dump ("a", a);
+		dump ("res", res);
+		abort ();
+	      }
+	    output[0] = 17;
+	    output[1+in_count*size] = 17;
+
+	    mpz_export (output+1, &out_count, order, size, endian, 0, a);
+	    if (out_count != in_count
+		|| memcmp (output+1, input, in_count * size)
+		|| output[0] != 17
+		|| output[1+in_count*size] != 17)
+	      {
+		fprintf (stderr, "mpz_export failed:\n"
+			 "in_count %d, out_count %d, endian = %d, order = %d\n",
+			 in_count, out_count, endian, order);
+		dump_bytes ("input", input, in_count * size);
+		dump_bytes ("output", output+1, out_count * size);
+		if (output[0] != 17)
+		  fprintf (stderr, "Overwrite at -1, value %02x\n", output[0]);
+		if (output[1+in_count*size] != 17)
+		  fprintf (stderr, "Overwrite at %d, value %02x\n",
+			   in_count*size, output[1+in_count*size]);
+
+		abort ();
+	      }
+	  }
+  mpz_clear (a);
+  mpz_clear (res);
+}


More information about the gmp-commit mailing list