[Gmp-commit] /home/hgfiles/gmp: New test for mpn_invert.

mercurial at gmplib.org mercurial at gmplib.org
Fri Dec 18 19:36:05 CET 2009


details:   /home/hgfiles/gmp/rev/262bb5b4cbf5
changeset: 13130:262bb5b4cbf5
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Fri Dec 18 19:36:00 2009 +0100
description:
New test for mpn_invert.

diffstat:

 ChangeLog             |    2 +
 tests/mpn/Makefile.am |   11 +-
 tests/mpn/t-invert.c  |  160 ++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 168 insertions(+), 5 deletions(-)

diffs (197 lines):

diff -r a4832080f3d5 -r 262bb5b4cbf5 ChangeLog
--- a/ChangeLog	Fri Dec 18 16:26:49 2009 +0100
+++ b/ChangeLog	Fri Dec 18 19:36:00 2009 +0100
@@ -25,6 +25,8 @@
 
 2009-12-18  Marco Bodrato <bodrato at mail.dm.unipi.it>
 
+	* tests/mpn/t-invert.c: New test program.
+
 	* mpn/generic/toom63_mul.c: New file.
 	* mpn/generic/toom_interpolate_8pts.c: New file.
 	* gmp-impl.h: Provide corresponding declarations.
diff -r a4832080f3d5 -r 262bb5b4cbf5 tests/mpn/Makefile.am
--- a/tests/mpn/Makefile.am	Fri Dec 18 16:26:49 2009 +0100
+++ b/tests/mpn/Makefile.am	Fri Dec 18 19:36:00 2009 +0100
@@ -21,11 +21,12 @@
 INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/tests
 LDADD = $(top_builddir)/tests/libtests.la $(top_builddir)/libgmp.la
 
-check_PROGRAMS = t-asmtype t-aors_1 t-divrem_1 t-fat t-get_d \
-  t-instrument t-iord_u t-mp_bases t-perfsqr t-scan \
-  t-toom22 t-toom32 t-toom33 t-toom42 t-toom43 t-toom44 \
-  t-toom52 t-toom53 t-toom62 t-toom63 \
-  t-bdiv t-hgcd t-matrix22 t-mullo t-mulmod_bnm1 t-sqrmod_bnm1
+check_PROGRAMS = t-asmtype t-aors_1 t-divrem_1 t-fat t-get_d	\
+  t-instrument t-iord_u t-mp_bases t-perfsqr t-scan		\
+  t-toom22 t-toom32 t-toom33 t-toom42 t-toom43 t-toom44 	\
+  t-toom52 t-toom53 t-toom62 t-toom63				\
+  t-bdiv t-hgcd t-matrix22 t-mullo t-mulmod_bnm1 t-sqrmod_bnm1	\
+  t-invert
 
 EXTRA_DIST = toom-shared.h
 
diff -r a4832080f3d5 -r 262bb5b4cbf5 tests/mpn/t-invert.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/mpn/t-invert.c	Fri Dec 18 19:36:00 2009 +0100
@@ -0,0 +1,160 @@
+/* Test for mpn_invert function.
+
+   Contributed to the GNU project by Marco Bodrato.
+
+Copyright 2009 Free Software Foundation, Inc.
+
+This file is part of the GNU MP Library.
+
+The GNU MP Library is free software; you can redistribute it and/or modify
+it under the terms of the GNU Lesser 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 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 Lesser General Public
+License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
+
+
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "tests.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+
+/* Sizes are up to 2^SIZE_LOG limbs */
+#ifndef SIZE_LOG
+#define SIZE_LOG 12
+#endif
+
+#ifndef COUNT
+#define COUNT 300
+#endif
+
+#define MAX_N (1L << SIZE_LOG)
+#define MIN_N 1
+
+
+static int
+invert_valid (mp_srcptr ip, mp_srcptr dp, mp_size_t n)
+{
+  mp_ptr tp;
+  int cy;
+  TMP_DECL;
+
+  TMP_MARK;
+  tp = TMP_ALLOC_LIMBS (2*n);
+
+  refmpn_mul (tp, ip, n, dp, n);
+  cy  = refmpn_add_n (tp + n, tp + n, dp, n); /* This must not give a carry. */
+  cy -= refmpn_add (tp, tp, 2*n, dp, n); /* This must give a carry. */
+  TMP_FREE;
+
+  return (cy == -1);
+}
+
+/*
+  Chech the result of the mpn_invert function in the library.
+*/
+
+int
+main (int argc, char **argv)
+{
+  mp_ptr ip, dp, scratch;
+  int count = COUNT;
+  int test;
+  gmp_randstate_ptr rands;
+  TMP_DECL;
+  TMP_MARK;
+
+  if (argc > 1)
+    {
+      char *end;
+      count = strtol (argv[1], &end, 0);
+      if (*end || count <= 0)
+	{
+	  fprintf (stderr, "Invalid test count: %s.\n", argv[1]);
+	  return 1;
+	}
+    }
+
+  tests_start ();
+  rands = RANDS;
+
+  dp = TMP_ALLOC_LIMBS (MAX_N);
+  ip = 1+TMP_ALLOC_LIMBS (MAX_N + 2);
+  scratch
+    = 1+TMP_ALLOC_LIMBS (mpn_invert_itch (MAX_N) + 2);
+
+  for (test = 0; test < count; test++)
+    {
+      unsigned size_min;
+      unsigned size_range;
+      mp_size_t n;
+      mp_size_t itch;
+      mp_limb_t i_before, i_after, s_before, s_after;
+
+      for (size_min = 1; (1L << size_min) < MIN_N; size_min++)
+	;
+
+      /* We generate an in the MIN_N <= n <= (1 << size_range). */
+      size_range = size_min
+	+ gmp_urandomm_ui (rands, SIZE_LOG + 1 - size_min);
+
+      n = MIN_N
+	+ gmp_urandomm_ui (rands, (1L << size_range) + 1 - MIN_N);
+
+      mpn_random2 (dp, n);
+
+      mpn_random2 (ip-1, n + 2);
+      i_before = ip[-1];
+      i_after = ip[n];
+
+      itch = mpn_invert_itch (n);
+      ASSERT_ALWAYS (itch <= mpn_invert_itch (MAX_N));
+      mpn_random2 (scratch-1, itch+2);
+      s_before = scratch[-1];
+      s_after = scratch[itch];
+
+      dp[n-1] |= GMP_NUMB_HIGHBIT;
+      mpn_invert (ip, dp, n, scratch);
+      if (ip[-1] != i_before || ip[n] != i_after
+	  || scratch[-1] != s_before || scratch[itch] != s_after
+	  || ! invert_valid(ip, dp, n))
+	{
+	  printf ("ERROR in test %d, n = %d\n",
+		  test, (int) n);
+	  if (ip[-1] != i_before)
+	    {
+	      printf ("before ip:"); mpn_dump (ip -1, 1);
+	      printf ("keep:   "); mpn_dump (&i_before, 1);
+	    }
+	  if (ip[n] != i_after)
+	    {
+	      printf ("after ip:"); mpn_dump (ip + n, 1);
+	      printf ("keep:   "); mpn_dump (&i_after, 1);
+	    }
+	  if (scratch[-1] != s_before)
+	    {
+	      printf ("before scratch:"); mpn_dump (scratch-1, 1);
+	      printf ("keep:   "); mpn_dump (&s_before, 1);
+	    }
+	  if (scratch[itch] != s_after)
+	    {
+	      printf ("after scratch:"); mpn_dump (scratch + itch, 1);
+	      printf ("keep:   "); mpn_dump (&s_after, 1);
+	    }
+	  mpn_dump (dp, n);
+	  mpn_dump (ip, n);
+
+	  abort();
+	}
+    }
+  TMP_FREE;
+  return 0;
+}


More information about the gmp-commit mailing list