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

mercurial at gmplib.org mercurial at gmplib.org
Fri Jan 11 09:20:20 CET 2013


details:   /var/hg/gmp/rev/33f3ccfb0379
changeset: 15255:33f3ccfb0379
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Fri Jan 11 09:13:44 2013 +0100
description:
mini-gmp/tests/t-comb.c: New test program

details:   /var/hg/gmp/rev/223bdf876788
changeset: 15256:223bdf876788
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Fri Jan 11 09:14:48 2013 +0100
description:
mini-gmp/mini-gmp.c (mpz_fac_ui,mpz_bin_uiui): Rewrite.

details:   /var/hg/gmp/rev/5726b8afa3b0
changeset: 15257:5726b8afa3b0
user:      Marco Bodrato <bodrato at mail.dm.unipi.it>
date:      Fri Jan 11 09:16:39 2013 +0100
description:
ChangeLog

diffstat:

 ChangeLog               |   14 ++-
 mini-gmp/mini-gmp.c     |   27 +++----
 mini-gmp/tests/Makefile |    2 +-
 mini-gmp/tests/t-comb.c |  167 ++++++++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 190 insertions(+), 20 deletions(-)

diffs (256 lines):

diff -r 06eaffc59c1b -r 5726b8afa3b0 ChangeLog
--- a/ChangeLog	Thu Jan 10 21:32:53 2013 +0100
+++ b/ChangeLog	Fri Jan 11 09:16:39 2013 +0100
@@ -1,7 +1,10 @@
-2013-01-10  Torbjorn Granlund  <tege at gmplib.org>
-
-	* Makefile.am (check-mini-gmp): Set LD_LIBRARY_PATH to allow testing
-	with dynamic main GMP build.
+2013-01-11 Marco Bodrato <bodrato at mail.dm.unipi.it>
+
+	* mini-gmp/tests/t-comb.c: New test program, testing both
+	mpz_fac_ui and mpz_bin_uiui.
+	* mini-gmp/tests/Makefile (CHECK_PROGRAMS): Added t-comb.
+	* mini-gmp/mini-gmp.c (mpz_fac_ui): Remove a branch.
+	(mpz_bin_uiui): Rewrite.
 
 2013-01-10 Marco Bodrato <bodrato at mail.dm.unipi.it>
 
@@ -13,6 +16,9 @@
 
 	* mini-gmp/tests/t-import.c (main): Don't drop off functon end.
 
+	* Makefile.am (check-mini-gmp): Set LD_LIBRARY_PATH to allow testing
+	with dynamic main GMP build.
+
 2013-01-09 Marco Bodrato <bodrato at mail.dm.unipi.it>
 
 	* mini-gmp/mini-gmp.c (mpz_export): Support op=0 countp=NULL.
diff -r 06eaffc59c1b -r 5726b8afa3b0 mini-gmp/mini-gmp.c
--- a/mini-gmp/mini-gmp.c	Thu Jan 10 21:32:53 2013 +0100
+++ b/mini-gmp/mini-gmp.c	Fri Jan 11 09:16:39 2013 +0100
@@ -3184,29 +3184,26 @@
 void
 mpz_fac_ui (mpz_t x, unsigned long n)
 {
-  if (n < 2) {
-    mpz_set_ui (x, 1);
-    return;
-  }
-  mpz_set_ui (x, n);
-  for (;--n > 1;)
-    mpz_mul_ui (x, x, n);
+  mpz_set_ui (x, n + (n == 0));
+  for (;n > 2;)
+    mpz_mul_ui (x, x, --n);
 }
 
 void
 mpz_bin_uiui (mpz_t r, unsigned long n, unsigned long k)
 {
   mpz_t t;
-
-  if (k > n) {
-    r->_mp_size = 0;
-    return;
-  }
-  mpz_fac_ui (r, n);
+  mpz_set_ui (r, k <= n);
+
+  if (k > (n >> 1))
+    k = (k <= n) ? n - k : 0;
+
   mpz_init (t);
   mpz_fac_ui (t, k);
-  mpz_divexact (r, r, t);
-  mpz_fac_ui (t, n - k);
+
+  for (; k > 0; k--)
+      mpz_mul_ui (r, r, n--);
+
   mpz_divexact (r, r, t);
   mpz_clear (t);
 }
diff -r 06eaffc59c1b -r 5726b8afa3b0 mini-gmp/tests/Makefile
--- a/mini-gmp/tests/Makefile	Thu Jan 10 21:32:53 2013 +0100
+++ b/mini-gmp/tests/Makefile	Fri Jan 11 09:16:39 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-import \
+	t-double t-gcd t-lcm t-import t-comb \
 	t-sqrt t-root t-powm t-logops t-bitops t-scan t-str \
 	t-reuse
 
diff -r 06eaffc59c1b -r 5726b8afa3b0 mini-gmp/tests/t-comb.c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mini-gmp/tests/t-comb.c	Fri Jan 11 09:16:39 2013 +0100
@@ -0,0 +1,167 @@
+/* Exercise mpz_fac_ui and mpz_bin_uiui.
+
+Copyright 2000, 2001, 2002, 2012, 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 <stdio.h>
+#include <stdlib.h>
+
+#include "mini-gmp.h"
+
+/* Usage: t-fac_ui [x|num]
+
+   With no arguments testing goes up to the initial value of "limit" below.
+   With a number argument tests are carried that far, or with a literal "x"
+   tests are continued without limit (this being meant only for development
+   purposes).  */
+
+void
+try_mpz_bin_uiui (mpz_srcptr want, unsigned long n, unsigned long k)
+{
+  mpz_t  got;
+
+  mpz_init (got);
+  mpz_bin_uiui (got, n, k);
+  if (mpz_cmp (got, want) != 0)
+    {
+      printf ("mpz_bin_uiui wrong\n");
+      printf ("  n=%lu\n", n);
+      printf ("  k=%lu\n", k);
+      printf ("  got="); mpz_out_str (stdout, 10, got); printf ("\n");
+      printf ("  want="); mpz_out_str (stdout, 10, want); printf ("\n");
+      abort();
+    }
+  mpz_clear (got);
+}
+
+/* Test all bin(n,k) cases, with 0 <= k <= n + 1 <= count.  */
+void
+bin_smallexaustive (unsigned int count)
+{
+  mpz_t          want;
+  unsigned long  n, k;
+  int            tests;
+
+  mpz_init (want);
+
+  for (n = 0; n < count; n++)
+    {
+      mpz_set_ui (want, 1);
+      for (k = 0; k <= n; k++)
+	{
+	  try_mpz_bin_uiui (want, n, k);
+	  mpz_mul_ui (want, want, n - k);
+	  mpz_fdiv_q_ui (want, want, k + 1);
+	}
+      try_mpz_bin_uiui (want, n, k);
+    }
+
+  mpz_clear (want);
+}
+
+/* Test all fac(n) cases, with 0 <= n <= limit.  */
+void
+fac_smallexaustive (unsigned int limit)
+{
+  mpz_t          f, r;
+  unsigned long  n;
+  mpz_init_set_si (f, 1);  /* 0! = 1 */
+  mpz_init (r);
+
+  for (n = 0; n < limit; n++)
+    {
+      mpz_fac_ui (r, n);
+
+      if (mpz_cmp (f, r) != 0)
+        {
+          printf ("mpz_fac_ui(%lu) wrong\n", n);
+          printf ("  got  "); mpz_out_str (stdout, 10, r); printf("\n");
+          printf ("  want "); mpz_out_str (stdout, 10, f); printf("\n");
+          abort ();
+        }
+
+      mpz_mul_ui (f, f, n+1);  /* (n+1)! = n! * (n+1) */
+    }
+
+  mpz_clear (f);
+  mpz_clear (r);
+}
+
+void checkWilson (mpz_t f, unsigned long n)
+{
+  unsigned long m;
+
+  mpz_fac_ui (f, n - 1);
+  m = mpz_fdiv_ui (f, n);
+  if ( m != n - 1)
+    {
+      printf ("mpz_fac_ui(%lu) wrong\n", n - 1);
+      printf ("  Wilson's theorem not verified: got %lu, expected %lu.\n",m ,n - 1);
+      abort ();
+    }
+}
+
+void
+checkprimes (unsigned long p1, unsigned long p2, unsigned long p3)
+{
+  mpz_t          b, f;
+
+  if (p1 - 1 != p2 - 1 + p3 - 1)
+    {
+      printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3);
+      printf (" %lu - 1 != %lu - 1 + %lu - 1 \n", p1, p2, p3);
+      abort ();
+    }
+
+  mpz_init (b);
+  mpz_init (f);
+
+  checkWilson (b, p1); /* b = (p1-1)! */
+  checkWilson (f, p2); /* f = (p2-1)! */
+  mpz_divexact (b, b, f);
+  checkWilson (f, p3); /* f = (p3-1)! */
+  mpz_divexact (b, b, f); /* b = (p1-1)!/((p2-1)!(p3-1)!) */
+  mpz_bin_uiui (f, p1 - 1, p2 - 1);
+  if (mpz_cmp (f, b) != 0)
+    {
+      printf ("checkprimes(%lu, %lu, %lu) wrong\n", p1, p2, p3);
+      printf ("  got  "); mpz_out_str (stdout, 10, b); printf("\n");
+      printf ("  want "); mpz_out_str (stdout, 10, f); printf("\n");
+      abort ();
+    }
+
+  mpz_clear (b);
+  mpz_clear (f);
+
+}
+
+int
+main (int argc, char *argv[])
+{
+  unsigned long  limit = 128;
+
+  if (argc > 1 && argv[1][0] == 'x')
+    limit = ~ limit;
+  else if (argc > 1)
+    limit = atoi (argv[1]);
+
+  checkprimes(1009, 733, 277);
+  fac_smallexaustive (limit);
+  bin_smallexaustive (limit);
+
+  return 0;
+}


More information about the gmp-commit mailing list