summaryrefslogtreecommitdiff
path: root/gnu/lib/libgmp/mpz/tests
diff options
context:
space:
mode:
authorNiels Provos <provos@cvs.openbsd.org>1997-06-24 21:28:32 +0000
committerNiels Provos <provos@cvs.openbsd.org>1997-06-24 21:28:32 +0000
commit2797d26f259dcf820a086e4110ca53c2db78bc5d (patch)
treefa8f850d5b10a0f6fab21154cc60c759de02ddb2 /gnu/lib/libgmp/mpz/tests
parent6d71925e98a49e80463b5f54135da67389b7ddea (diff)
import of libgmp-2.0.2. Makefile.bsd-wrappers need to be worked on.
Diffstat (limited to 'gnu/lib/libgmp/mpz/tests')
-rw-r--r--gnu/lib/libgmp/mpz/tests/Makefile.in126
-rw-r--r--gnu/lib/libgmp/mpz/tests/configure.in11
-rw-r--r--gnu/lib/libgmp/mpz/tests/convert.c80
-rw-r--r--gnu/lib/libgmp/mpz/tests/dive.c87
-rw-r--r--gnu/lib/libgmp/mpz/tests/io-binary.c76
-rw-r--r--gnu/lib/libgmp/mpz/tests/io.c86
-rw-r--r--gnu/lib/libgmp/mpz/tests/logic.c103
-rw-r--r--gnu/lib/libgmp/mpz/tests/reuse.c135
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-fdiv.c118
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c117
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-gcd.c132
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-gcd2.c137
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-mul.c261
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-powm.c125
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-powm_ui.c120
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-sqrtrem.c98
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-tdiv.c118
-rw-r--r--gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c117
18 files changed, 2047 insertions, 0 deletions
diff --git a/gnu/lib/libgmp/mpz/tests/Makefile.in b/gnu/lib/libgmp/mpz/tests/Makefile.in
new file mode 100644
index 00000000000..5a0cf599e10
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/Makefile.in
@@ -0,0 +1,126 @@
+# Makefile for mpz/tests for GNU MP
+
+srcdir = .
+
+CC = gcc
+
+TEST_LIBS = ../../libgmp.a
+INCLUDES = -I../../mpn -I$(srcdir)/../..
+CFLAGS = -g -O
+
+.c.o:
+ $(CC) -c $(INCLUDES) $(CFLAGS) $(XCFLAGS) $<
+
+TEST_SRCS = t-mul.c t-tdiv.c t-tdiv_ui.c t-fdiv.c t-fdiv_ui.c t-gcd.c \
+ t-gcd2.c dive.c t-sqrtrem.c convert.c io.c logic.c t-powm.c t-powm_ui.c \
+ reuse.c
+TEST_OBJS = t-mul.o t-tdiv.o t-tdiv_ui.o t-fdiv.o t-fdiv_ui.o t-gcd.o \
+ t-gcd2.o dive.o t-sqrtrem.o convert.o io.o logic.o t-powm.o t-powm_ui.o \
+ reuse.o
+TESTS = t-mul t-tdiv t-tdiv_ui t-fdiv t-fdiv_ui t-gcd t-gcd2 \
+ dive t-sqrtrem convert io logic t-powm t-powm_ui reuse
+
+check: Makefile st-mul st-tdiv st-tdiv_ui st-fdiv st-fdiv_ui st-gcd st-gcd2 st-dive \
+ st-sqrtrem st-convert st-io st-logic st-powm st-powm_ui st-reuse
+ @echo "The tests passed."
+
+st-mul: t-mul
+ ./t-mul
+ touch $@
+st-tdiv: t-tdiv
+ ./t-tdiv
+ touch $@
+st-tdiv_ui: t-tdiv_ui
+ ./t-tdiv_ui
+ touch $@
+st-fdiv: t-fdiv
+ ./t-fdiv
+ touch $@
+st-fdiv_ui: t-fdiv_ui
+ ./t-fdiv_ui
+ touch $@
+st-gcd: t-gcd
+ ./t-gcd
+ touch $@
+st-gcd2: t-gcd2
+ ./t-gcd2
+ touch $@
+st-dive: dive
+ ./dive
+ touch $@
+st-sqrtrem: t-sqrtrem
+ ./t-sqrtrem
+ touch $@
+st-convert: convert
+ ./convert
+ touch $@
+st-io: io
+ ./io
+ touch $@
+st-logic: logic
+ ./logic
+ touch $@
+st-powm: t-powm
+ ./t-powm
+ touch $@
+st-powm_ui: t-powm_ui
+ ./t-powm_ui
+ touch $@
+st-reuse: reuse
+ ./reuse
+ touch $@
+
+t-mul: t-mul.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-tdiv: t-tdiv.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-tdiv_ui: t-tdiv_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-fdiv: t-fdiv.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-fdiv_ui: t-fdiv_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-gcd: t-gcd.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-gcd2: t-gcd2.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+dive: dive.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-sqrtrem: t-sqrtrem.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+convert: convert.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+io: io.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+logic: logic.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-powm: t-powm.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+t-powm_ui: t-powm_ui.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+reuse: reuse.o $(TEST_LIBS)
+ $(CC) -o $@ $@.o $(TEST_LIBS) $(CFLAGS)
+
+t-mul.o: $(srcdir)/t-mul.c
+t-tdiv.o: $(srcdir)/t-tdiv.c
+t-tdiv_ui.o: $(srcdir)/t-tdiv_ui.c
+t-fdiv.o: $(srcdir)/t-fdiv.c
+t-fdiv_ui.o: $(srcdir)/t-fdiv_ui.c
+t-gcd.o: $(srcdir)/t-gcd.c
+t-gcd2.o: $(srcdir)/t-gcd2.c
+dive.o: $(srcdir)/dive.c
+t-sqrtrem.o: $(srcdir)/t-sqrtrem.c
+convert.o: $(srcdir)/convert.c
+io.o: $(srcdir)/io.c
+logic.o: $(srcdir)/logic.c
+t-powm.o: $(srcdir)/t-powm.c
+t-powm_ui.o: $(srcdir)/t-powm_ui.c
+reuse.o: $(srcdir)/reuse.c
+
+clean mostlyclean:
+ rm -f *.o st-* $(TESTS)
+distclean maintainer-clean: clean
+ rm -f Makefile config.status
+
+Makefile: $(srcdir)/Makefile.in
+ $(SHELL) ./config.status
diff --git a/gnu/lib/libgmp/mpz/tests/configure.in b/gnu/lib/libgmp/mpz/tests/configure.in
new file mode 100644
index 00000000000..dacc177418d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/configure.in
@@ -0,0 +1,11 @@
+# This file is a shell script that supplies the information necessary
+# to tailor a template configure script into the configure script
+# appropriate for this directory. For more information, check any
+# existing configure script.
+
+srctrigger=t-mul.c
+srcname="gmp/mpz/tests"
+
+# per-host:
+
+# per-target:
diff --git a/gnu/lib/libgmp/mpz/tests/convert.c b/gnu/lib/libgmp/mpz/tests/convert.c
new file mode 100644
index 00000000000..1d8237099ca
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/convert.c
@@ -0,0 +1,80 @@
+/* Test conversion using mpz_get_str and mpz_set_str.
+
+Copyright (C) 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 32
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 100000;
+ char *str;
+ int base;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&op1);
+ mpz_init (&op2);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (&op1, size);
+ base = urandom () % 36 + 1;
+ if (base == 1)
+ base = 0;
+
+ str = mpz_get_str ((char *) 0, base, &op1);
+ mpz_set_str (&op2, str, base);
+ free (str);
+
+ if (mpz_cmp (&op1, &op2))
+ {
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (&op1, -16);
+ fprintf (stderr, "base = %d\n", base);
+ abort ();
+ }
+ }
+
+ exit (0);
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/dive.c b/gnu/lib/libgmp/mpz/tests/dive.c
new file mode 100644
index 00000000000..8d3516d83a6
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/dive.c
@@ -0,0 +1,87 @@
+/* Test mpz_mul, mpz_divexact.
+
+Copyright (C) 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 32
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t op1, op2;
+ mpz_t prod, quot;
+ mp_size_t size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (prod);
+ mpz_init (quot);
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (op1, size);
+
+ do
+ {
+ size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (op2, size);
+ }
+ while (mpz_cmp_ui (op2, 0) == 0);
+
+ mpz_mul (prod, op1, op2);
+
+ mpz_divexact (quot, prod, op2);
+ if (mpz_cmp (quot, op1) != 0)
+ dump_abort (quot, op1);
+ }
+
+ exit (0);
+}
+
+dump_abort (op1, op2)
+ mpz_t op1, op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "ref = "); debug_mp (op1, -16);
+ fprintf (stderr, "wrong = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/io-binary.c b/gnu/lib/libgmp/mpz/tests/io-binary.c
new file mode 100644
index 00000000000..c28f2a5ba73
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/io-binary.c
@@ -0,0 +1,76 @@
+/* Test mpz_inp_binary and mpz_out_binary.
+
+ We write and read back some test strings, and both compare
+ the numerical result, and make sure the pattern on file is
+ what we expect. The latter is important for compatibility
+ between machines with different word sizes. */
+
+#include <stdio.h>
+#include "gmp.h"
+
+FILE *file;
+
+test (str, binary_len, binary_str)
+ char *str;
+ int binary_len;
+ char *binary_str;
+{
+ mpz_t x, y;
+ int n_written;
+ char buf[100];
+
+ mpz_init_set_str (x, str, 0);
+ mpz_init (y);
+
+ fseek (file, 0, SEEK_SET);
+ mpz_out_binary (file, x);
+ n_written = ftell (file);
+ if (n_written != binary_len)
+ abort ();
+
+ fseek (file, 0, SEEK_SET);
+ mpz_inp_binary (y, file);
+ if (n_written != ftell (file))
+ abort ();
+ if (mpz_cmp (x, y) != 0)
+ abort ();
+
+ fseek (file, 0, SEEK_SET);
+ fread (buf, n_written, 1, file);
+ if (memcmp (buf, binary_str, binary_len) != 0)
+ abort ();
+
+ mpz_clear (x);
+}
+
+main ()
+{
+ file = fopen ("xtmpfile", "w+");
+
+ test ("0", 4,
+ "\000\000\000\000");
+
+ test ("1", 5,
+ "\000\000\000\001\001");
+ test ("0x123", 6,
+ "\000\000\000\002\001\043");
+ test ("0xdeadbeef", 8,
+ "\000\000\000\004\336\255\276\357");
+ test ("0xbabefaced", 9,
+ "\000\000\000\005\013\253\357\254\355");
+ test ("0x123456789facade0", 12,
+ "\000\000\000\010\022\064\126\170\237\254\255\340");
+
+ test ("-1", 5,
+ "\377\377\377\377\001");
+ test ("-0x123", 6,
+ "\377\377\377\376\001\043");
+ test ("-0xdeadbeef", 8,
+ "\377\377\377\374\336\255\276\357");
+ test ("-0xbabefaced", 9,
+ "\377\377\377\373\013\253\357\254\355");
+ test ("-0x123456789facade0", 12,
+ "\377\377\377\370\022\064\126\170\237\254\255\340");
+
+ exit (0);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/io.c b/gnu/lib/libgmp/mpz/tests/io.c
new file mode 100644
index 00000000000..3dfa9a569e9
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/io.c
@@ -0,0 +1,86 @@
+/* Test conversion and I/O using mpz_out_str and mpz_inp_str.
+
+Copyright (C) 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ MP_INT op1, op2;
+ mp_size_t size;
+ int i;
+ int reps = 10000;
+ FILE *fsin, *fsout;
+ int fd[2];
+ int base;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (&op1);
+ mpz_init (&op2);
+
+ pipe (fd);
+ fsin = fdopen (fd[0], "r");
+ fsout = fdopen (fd[1], "w");
+
+ for (i = 0; i < reps; i++)
+ {
+ size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (&op1, size);
+ base = urandom () % 36 + 1;
+ if (base == 1)
+ base = 0;
+
+ mpz_out_str (fsout, base, &op1);
+ putc (' ', fsout);
+ fflush (fsout);
+ mpz_inp_str (&op2, fsin, base);
+
+ if (mpz_cmp (&op1, &op2))
+ {
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (&op1, -16);
+ fprintf (stderr, "base = %d\n", base);
+ abort ();
+ }
+ }
+
+ exit (0);
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/logic.c b/gnu/lib/libgmp/mpz/tests/logic.c
new file mode 100644
index 00000000000..41a8cac9083
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/logic.c
@@ -0,0 +1,103 @@
+/* Test mpz_com, mpz_and, and mpz_ior.
+
+Copyright (C) 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t x, y, r1, r2;
+ mpz_t t1, t2, t3, t4;
+ mp_size_t xsize, ysize;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (x);
+ mpz_init (y);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (t1);
+ mpz_init (t2);
+ mpz_init (t3);
+ mpz_init (t4);
+
+ for (i = 0; i < reps; i++)
+ {
+ xsize = urandom () % SIZE - SIZE/2;
+ mpz_random2 (x, xsize);
+
+ ysize = urandom () % SIZE - SIZE/2;
+ mpz_random2 (y, ysize);
+
+ mpz_com (r1, x);
+ mpz_com (r1, r1);
+ if (mpz_cmp (r1, x) != 0)
+ dump_abort ();
+
+ mpz_com (r1, y);
+ mpz_com (r2, r1);
+ if (mpz_cmp (r2, y) != 0)
+ dump_abort ();
+
+ mpz_com (t1, x);
+ mpz_com (t2, y);
+ mpz_and (t3, t1, t2);
+ mpz_com (r1, t3);
+ mpz_ior (r2, x, y);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+
+ mpz_com (t1, x);
+ mpz_com (t2, y);
+ mpz_ior (t3, t1, t2);
+ mpz_com (r1, t3);
+ mpz_and (r2, x, y);
+ if (mpz_cmp (r1, r2) != 0)
+ dump_abort ();
+ }
+
+ exit (0);
+}
+
+dump_abort ()
+{
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/reuse.c b/gnu/lib/libgmp/mpz/tests/reuse.c
new file mode 100644
index 00000000000..52fc5a51677
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/reuse.c
@@ -0,0 +1,135 @@
+/* Test that routines allow reusing a source variable as destination. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+#if __STDC__
+typedef void (*dss_func) (mpz_ptr, mpz_srcptr, mpz_srcptr);
+#else
+typedef void (*dss_func) ();
+#endif
+
+dss_func dss_funcs[] =
+{
+ mpz_add, mpz_and, mpz_cdiv_q, mpz_cdiv_r, mpz_fdiv_q, mpz_fdiv_r,
+ mpz_gcd, mpz_ior, mpz_mul, mpz_sub, mpz_tdiv_q, mpz_tdiv_r
+};
+
+char *dss_func_names[] =
+{
+ "mpz_add", "mpz_and", "mpz_cdiv_q", "mpz_cdiv_r", "mpz_fdiv_q", "mpz_fdiv_r",
+ "mpz_gcd", "mpz_ior", "mpz_mul", "mpz_sub", "mpz_tdiv_q", "mpz_tdiv_r"
+};
+
+char dss_func_division[] = {0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1};
+
+#if 0
+mpz_divexact /* requires special operands */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ int i;
+ int pass, reps = 10000;
+ mpz_t in1, in2, out1;
+ mpz_t res1, res2, res3;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (in1);
+ mpz_init (in2);
+ mpz_init (out1);
+ mpz_init (res1);
+ mpz_init (res2);
+ mpz_init (res3);
+
+ for (pass = 1; pass <= reps; pass++)
+ {
+ mpz_random (in1, urandom () % SIZE - SIZE/2);
+ mpz_random (in2, urandom () % SIZE - SIZE/2);
+
+ for (i = 0; i < sizeof (dss_funcs) / sizeof (dss_func); i++)
+ {
+ if (dss_func_division[i] && mpz_cmp_ui (in2, 0) == 0)
+ continue;
+
+ (dss_funcs[i]) (res1, in1, in2);
+
+ mpz_set (out1, in1);
+ (dss_funcs[i]) (out1, out1, in2);
+ mpz_set (res2, out1);
+
+ mpz_set (out1, in2);
+ (dss_funcs[i]) (out1, in1, out1);
+ mpz_set (res3, out1);
+
+ if (mpz_cmp (res1, res2) != 0)
+ dump_abort (dss_func_names[i], in1, in2);
+ if (mpz_cmp (res1, res3) != 0)
+ dump_abort (dss_func_names[i], in1, in2);
+ }
+ }
+
+ exit (0);
+}
+
+dump_abort (name, in1, in2)
+ char *name;
+ mpz_t in1, in2;
+{
+ printf ("failure in %s (", name);
+ mpz_out_str (stdout, -16, in1);
+ printf (" ");
+ mpz_out_str (stdout, -16, in2);
+ printf (")\n");
+ abort ();
+}
+
+#if 0
+void mpz_add_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_div_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mod_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mul_2exp _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_mul_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_pow_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_sub_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+void mpz_tdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+
+void mpz_abs _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_com _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_sqrt _PROTO ((mpz_ptr, mpz_srcptr));
+void mpz_neg _PROTO ((mpz_ptr, mpz_srcptr));
+
+void mpz_tdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+
+void mpz_powm_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int, mpz_srcptr));
+
+void mpz_gcdext _PROTO ((mpz_ptr, mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+
+void mpz_cdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_fdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+void mpz_tdiv_qr _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr));
+
+void mpz_powm _PROTO ((mpz_ptr, mpz_srcptr, mpz_srcptr, mpz_srcptr));
+
+void mpz_sqrtrem _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr));
+
+unsigned long int mpz_cdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_qr_ui _PROTO ((mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long int));
+
+unsigned long int mpz_cdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_cdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_q_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_fdiv_r_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+unsigned long int mpz_gcd_ui _PROTO ((mpz_ptr, mpz_srcptr, unsigned long int));
+#endif
diff --git a/gnu/lib/libgmp/mpz/tests/t-fdiv.c b/gnu/lib/libgmp/mpz/tests/t-fdiv.c
new file mode 100644
index 00000000000..9de22d703f3
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-fdiv.c
@@ -0,0 +1,118 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr, mpz_fdiv_q,
+ mpz_fdiv_r, mpz_mul.
+
+Copyright (C) 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend, divisor;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (divisor);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (divisor, divisor_size);
+ if (mpz_cmp_ui (divisor, 0) == 0)
+ continue;
+
+ mpz_fdiv_qr (quotient, remainder, dividend, divisor);
+ mpz_fdiv_q (quotient2, dividend, divisor);
+ mpz_fdiv_r (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (divisor, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (temp, divisor);
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp (remainder, temp) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend, divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c b/gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c
new file mode 100644
index 00000000000..74ba9fcf7b2
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-fdiv_ui.c
@@ -0,0 +1,117 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_fdiv_qr_ui, mpz_fdiv_q_ui,
+ mpz_fdiv_r_ui, mpz_mul, mpz_mul_ui.
+
+Copyright (C) 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ mp_limb_t divisor;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor = urandom ();
+ if (divisor == 0)
+ continue;
+
+ mpz_fdiv_qr_ui (quotient, remainder, dividend, divisor);
+ mpz_fdiv_q_ui (quotient2, dividend, divisor);
+ mpz_fdiv_r_ui (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the divisor
+ (quotient rounded towards minus infinity). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if (mpz_cmp_ui (remainder, 0) < 0)
+ dump_abort (dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend;
+ mp_limb_t divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-gcd.c b/gnu/lib/libgmp/mpz/tests/t-gcd.c
new file mode 100644
index 00000000000..d9a78843a27
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-gcd.c
@@ -0,0 +1,132 @@
+/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_tdiv_r, mpz_add, mpz_cmp,
+ mpz_cmp_ui, mpz_init_set, mpz_set, mpz_clear.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void mpz_refgcd (), debug_mp ();
+
+#ifndef SIZE
+#define SIZE 256 /* really needs to be this large to exercise corner cases! */
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t op1, op2;
+ mpz_t refgcd, gcd, s, t;
+ mpz_t temp1, temp2;
+ mp_size_t op1_size, op2_size;
+ int i;
+ int reps = 1000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (refgcd);
+ mpz_init (gcd);
+ mpz_init (temp1);
+ mpz_init (temp2);
+ mpz_init (s);
+ mpz_init (t);
+
+ for (i = 0; i < reps; i++)
+ {
+ op1_size = urandom () % SIZE - SIZE/2;
+ op2_size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (op1, op1_size);
+ mpz_random2 (op2, op2_size);
+
+ mpz_refgcd (refgcd, op1, op2);
+
+ mpz_gcd (gcd, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_gcdext (gcd, s, t, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_mul (temp1, s, op1);
+ mpz_mul (temp2, t, op2);
+ mpz_add (gcd, temp1, temp2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refgcd (g, x, y)
+ mpz_t g;
+ mpz_t x, y;
+{
+ mpz_t xx, yy;
+
+ mpz_init (xx);
+ mpz_init (yy);
+
+ mpz_abs (xx, x);
+ mpz_abs (yy, y);
+
+ for (;;)
+ {
+ if (mpz_cmp_ui (yy, 0) == 0)
+ {
+ mpz_set (g, xx);
+ break;
+ }
+ mpz_tdiv_r (xx, xx, yy);
+ if (mpz_cmp_ui (xx, 0) == 0)
+ {
+ mpz_set (g, yy);
+ break;
+ }
+ mpz_tdiv_r (yy, yy, xx);
+ }
+
+ mpz_clear (xx);
+ mpz_clear (yy);
+}
+
+dump_abort (op1, op2)
+ mpz_t op1, op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-gcd2.c b/gnu/lib/libgmp/mpz/tests/t-gcd2.c
new file mode 100644
index 00000000000..b7ad67c034d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-gcd2.c
@@ -0,0 +1,137 @@
+/* Test mpz_gcd, mpz_gcdext, mpz_mul, mpz_tdiv_r, mpz_add, mpz_cmp,
+ mpz_cmp_ui, mpz_init_set, mpz_set, mpz_clear.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void mpz_refgcd (), debug_mp ();
+
+#ifndef SIZE
+#define SIZE 128
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t op1, op2, x;
+ mpz_t refgcd, gcd, s, t;
+ mpz_t temp1, temp2;
+ mp_size_t op1_size, op2_size, x_size;
+ int i;
+ int reps = 1000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (op1);
+ mpz_init (op2);
+ mpz_init (x);
+ mpz_init (refgcd);
+ mpz_init (gcd);
+ mpz_init (temp1);
+ mpz_init (temp2);
+ mpz_init (s);
+ mpz_init (t);
+
+ for (i = 0; i < reps; i++)
+ {
+ op1_size = urandom () % SIZE - SIZE/2;
+ op2_size = urandom () % SIZE - SIZE/2;
+ x_size = urandom () % SIZE/2;
+
+ mpz_random2 (op1, op1_size);
+ mpz_random2 (op2, op2_size);
+ mpz_random2 (x, x_size);
+ mpz_mul (op1, op1, x);
+ mpz_mul (op2, op2, x);
+
+ mpz_refgcd (refgcd, op1, op2);
+
+ mpz_gcd (gcd, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_gcdext (gcd, s, t, op1, op2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+
+ mpz_mul (temp1, s, op1);
+ mpz_mul (temp2, t, op2);
+ mpz_add (gcd, temp1, temp2);
+ if (mpz_cmp (refgcd, gcd))
+ dump_abort (op1, op2);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refgcd (g, x, y)
+ mpz_t g;
+ mpz_t x, y;
+{
+ mpz_t xx, yy;
+
+ mpz_init (xx);
+ mpz_init (yy);
+
+ mpz_abs (xx, x);
+ mpz_abs (yy, y);
+
+ for (;;)
+ {
+ if (mpz_cmp_ui (yy, 0) == 0)
+ {
+ mpz_set (g, xx);
+ break;
+ }
+ mpz_tdiv_r (xx, xx, yy);
+ if (mpz_cmp_ui (xx, 0) == 0)
+ {
+ mpz_set (g, yy);
+ break;
+ }
+ mpz_tdiv_r (yy, yy, xx);
+ }
+
+ mpz_clear (xx);
+ mpz_clear (yy);
+}
+
+dump_abort (op1, op2)
+ mpz_t op1, op2;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "op1 = "); debug_mp (op1, -16);
+ fprintf (stderr, "op2 = "); debug_mp (op2, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-mul.c b/gnu/lib/libgmp/mpz/tests/t-mul.c
new file mode 100644
index 00000000000..b200cd7585d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-mul.c
@@ -0,0 +1,261 @@
+/* Test mpz_add, mpz_cmp, mpz_cmp_ui, mpz_divmod, mpz_mul.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "longlong.h"
+#include "urandom.h"
+
+void debug_mp ();
+mp_size_t _mpn_mul_classic ();
+void mpz_refmul ();
+
+#ifndef SIZE
+#define SIZE 128
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t multiplier, multiplicand;
+ mpz_t product, ref_product;
+ mpz_t quotient, remainder;
+ mp_size_t multiplier_size, multiplicand_size;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (multiplier);
+ mpz_init (multiplicand);
+ mpz_init (product);
+ mpz_init (ref_product);
+ mpz_init (quotient);
+ mpz_init (remainder);
+
+ for (i = 0; i < reps; i++)
+ {
+ multiplier_size = urandom () % SIZE - SIZE/2;
+ multiplicand_size = urandom () % SIZE - SIZE/2;
+
+ mpz_random2 (multiplier, multiplier_size);
+ mpz_random2 (multiplicand, multiplicand_size);
+
+ mpz_mul (product, multiplier, multiplicand);
+ mpz_refmul (ref_product, multiplier, multiplicand);
+ if (mpz_cmp_ui (multiplicand, 0) != 0)
+ mpz_divmod (quotient, remainder, product, multiplicand);
+
+ if (mpz_cmp (product, ref_product))
+ dump_abort (multiplier, multiplicand);
+
+ if (mpz_cmp_ui (multiplicand, 0) != 0)
+ if (mpz_cmp_ui (remainder, 0) || mpz_cmp (quotient, multiplier))
+ dump_abort (multiplier, multiplicand);
+ }
+
+ exit (0);
+}
+
+void
+mpz_refmul (w, u, v)
+ mpz_t w;
+ const mpz_t u;
+ const mpz_t v;
+{
+ mp_size_t usize = u->_mp_size;
+ mp_size_t vsize = v->_mp_size;
+ mp_size_t wsize;
+ mp_size_t sign_product;
+ mp_ptr up, vp;
+ mp_ptr wp;
+ mp_ptr free_me = NULL;
+ size_t free_me_size;
+ TMP_DECL (marker);
+
+ TMP_MARK (marker);
+ sign_product = usize ^ vsize;
+ usize = ABS (usize);
+ vsize = ABS (vsize);
+
+ if (usize < vsize)
+ {
+ /* Swap U and V. */
+ {const __mpz_struct *t = u; u = v; v = t;}
+ {mp_size_t t = usize; usize = vsize; vsize = t;}
+ }
+
+ up = u->_mp_d;
+ vp = v->_mp_d;
+ wp = w->_mp_d;
+
+ /* Ensure W has space enough to store the result. */
+ wsize = usize + vsize;
+ if (w->_mp_alloc < wsize)
+ {
+ if (wp == up || wp == vp)
+ {
+ free_me = wp;
+ free_me_size = w->_mp_alloc;
+ }
+ else
+ (*_mp_free_func) (wp, w->_mp_alloc * BYTES_PER_MP_LIMB);
+
+ w->_mp_alloc = wsize;
+ wp = (mp_ptr) (*_mp_allocate_func) (wsize * BYTES_PER_MP_LIMB);
+ w->_mp_d = wp;
+ }
+ else
+ {
+ /* Make U and V not overlap with W. */
+ if (wp == up)
+ {
+ /* W and U are identical. Allocate temporary space for U. */
+ up = (mp_ptr) TMP_ALLOC (usize * BYTES_PER_MP_LIMB);
+ /* Is V identical too? Keep it identical with U. */
+ if (wp == vp)
+ vp = up;
+ /* Copy to the temporary space. */
+ MPN_COPY (up, wp, usize);
+ }
+ else if (wp == vp)
+ {
+ /* W and V are identical. Allocate temporary space for V. */
+ vp = (mp_ptr) TMP_ALLOC (vsize * BYTES_PER_MP_LIMB);
+ /* Copy to the temporary space. */
+ MPN_COPY (vp, wp, vsize);
+ }
+ }
+
+ wsize = _mpn_mul_classic (wp, up, usize, vp, vsize);
+ w->_mp_size = sign_product < 0 ? -wsize : wsize;
+ if (free_me != NULL)
+ (*_mp_free_func) (free_me, free_me_size * BYTES_PER_MP_LIMB);
+
+ TMP_FREE (marker);
+}
+
+mp_size_t
+_mpn_mul_classic (prodp, up, usize, vp, vsize)
+ mp_ptr prodp;
+ mp_srcptr up;
+ mp_size_t usize;
+ mp_srcptr vp;
+ mp_size_t vsize;
+{
+ mp_size_t i, j;
+ mp_limb_t prod_low, prod_high;
+ mp_limb_t cy_dig;
+ mp_limb_t v_limb, c;
+
+ if (vsize == 0)
+ return 0;
+
+ /* Offset UP and PRODP so that the inner loop can be faster. */
+ up += usize;
+ prodp += usize;
+
+ /* Multiply by the first limb in V separately, as the result can
+ be stored (not added) to PROD. We also avoid a loop for zeroing. */
+ v_limb = vp[0];
+ cy_dig = 0;
+ j = -usize;
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prodp[j], prod_high, prod_low, 0, cy_dig);
+ j++;
+ }
+ while (j < 0);
+
+ prodp[j] = cy_dig;
+ prodp++;
+
+ /* For each iteration in the outer loop, multiply one limb from
+ U with one limb from V, and add it to PROD. */
+ for (i = 1; i < vsize; i++)
+ {
+ v_limb = vp[i];
+ cy_dig = 0;
+ j = -usize;
+
+ /* Inner loops. Simulate the carry flag by jumping between
+ these loops. The first is used when there was no carry
+ in the previois iteration; the second when there was carry. */
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prod_low, prod_high, prod_low, 0, cy_dig);
+ c = prodp[j];
+ prod_low += c;
+ prodp[j] = prod_low;
+ if (prod_low < c)
+ goto cy_loop;
+ ncy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ prodp[j] = cy_dig;
+ prodp++;
+ continue;
+
+ do
+ {
+ umul_ppmm (prod_high, prod_low, up[j], v_limb);
+ add_ssaaaa (cy_dig, prod_low, prod_high, prod_low, 0, cy_dig);
+ c = prodp[j];
+ prod_low += c + 1;
+ prodp[j] = prod_low;
+ if (prod_low > c)
+ goto ncy_loop;
+ cy_loop:
+ j++;
+ }
+ while (j < 0);
+
+ cy_dig += 1;
+ prodp[j] = cy_dig;
+ prodp++;
+ }
+
+ return usize + vsize - (cy_dig == 0);
+}
+
+dump_abort (multiplier, multiplicand)
+ mpz_t multiplier, multiplicand;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "multiplier = "); debug_mp (multiplier, -16);
+ fprintf (stderr, "multiplicand = "); debug_mp (multiplicand, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-powm.c b/gnu/lib/libgmp/mpz/tests/t-powm.c
new file mode 100644
index 00000000000..02d7ca5d054
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-powm.c
@@ -0,0 +1,125 @@
+/* Test mpz_powm, mpz_mul. mpz_mod, mpz_mod_ui, mpz_div_ui.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t base, exp, mod;
+ mpz_t r1, r2, t1, exp2, base2;
+ mp_size_t base_size, exp_size, mod_size;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (base);
+ mpz_init (exp);
+ mpz_init (mod);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (t1);
+ mpz_init (exp2);
+ mpz_init (base2);
+
+ for (i = 0; i < reps; i++)
+ {
+ base_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (base, base_size);
+
+ exp_size = urandom () % SIZE;
+ mpz_random2 (exp, exp_size);
+
+ mod_size = urandom () % SIZE /* - SIZE/2 */;
+ mpz_random2 (mod, mod_size);
+ if (mpz_cmp_ui (mod, 0) == 0)
+ continue;
+
+ /* This is mathematically undefined. */
+ if (mpz_cmp_ui (base, 0) == 0 && mpz_cmp_ui (exp, 0) == 0)
+ continue;
+
+#if 0
+ putc ('\n', stderr);
+ debug_mp (base, -16);
+ debug_mp (exp, -16);
+ debug_mp (mod, -16);
+#endif
+
+ mpz_powm (r1, base, exp, mod);
+
+ mpz_set_ui (r2, 1);
+ mpz_set (base2, base);
+ mpz_set (exp2, exp);
+
+ mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */
+ while (mpz_cmp_ui (exp2, 0) != 0)
+ {
+ mpz_mod_ui (t1, exp2, 2);
+ if (mpz_cmp_ui (t1, 0) != 0)
+ {
+ mpz_mul (r2, r2, base2);
+ mpz_mod (r2, r2, mod);
+ }
+ mpz_mul (base2, base2, base2);
+ mpz_mod (base2, base2, mod);
+ mpz_div_ui (exp2, exp2, 2);
+ }
+
+#if 0
+ debug_mp (r1, -16);
+ debug_mp (r2, -16);
+#endif
+
+ if (mpz_cmp (r1, r2) != 0)
+ abort ();
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-powm_ui.c b/gnu/lib/libgmp/mpz/tests/t-powm_ui.c
new file mode 100644
index 00000000000..b88fa982077
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-powm_ui.c
@@ -0,0 +1,120 @@
+/* Test mpz_powm_ui, mpz_mul. mpz_mod, mpz_mod_ui, mpz_div_ui.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 8
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t base, mod;
+ mpz_t r1, r2, base2;
+ mp_size_t base_size, mod_size;
+ mp_limb_t exp, exp2;
+ int i;
+ int reps = 10000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (base);
+ mpz_init (mod);
+ mpz_init (r1);
+ mpz_init (r2);
+ mpz_init (base2);
+
+ for (i = 0; i < reps; i++)
+ {
+ base_size = urandom () % SIZE /* - SIZE/2 */;
+ mpz_random2 (base, base_size);
+
+ mpn_random2 (&exp, 1);
+
+ mod_size = urandom () % SIZE /* - SIZE/2 */;
+ mpz_random2 (mod, mod_size);
+ if (mpz_cmp_ui (mod, 0) == 0)
+ continue;
+
+ /* This is mathematically undefined. */
+ if (mpz_cmp_ui (base, 0) == 0 && exp == 0)
+ continue;
+
+#if 0
+ putc ('\n', stderr);
+ debug_mp (base, -16);
+ debug_mp (mod, -16);
+#endif
+
+ mpz_powm_ui (r1, base, (unsigned long int) exp, mod);
+
+ mpz_set_ui (r2, 1);
+ mpz_set (base2, base);
+ exp2 = exp;
+
+ mpz_mod (r2, r2, mod); /* needed when exp==0 and mod==1 */
+ while (exp2 != 0)
+ {
+ if (exp2 % 2 != 0)
+ {
+ mpz_mul (r2, r2, base2);
+ mpz_mod (r2, r2, mod);
+ }
+ mpz_mul (base2, base2, base2);
+ mpz_mod (base2, base2, mod);
+ exp2 = exp2 / 2;
+ }
+
+#if 0
+ debug_mp (r1, -16);
+ debug_mp (r2, -16);
+#endif
+
+ if (mpz_cmp (r1, r2) != 0)
+ abort ();
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ MP_INT *dividend, *divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ MP_INT *x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-sqrtrem.c b/gnu/lib/libgmp/mpz/tests/t-sqrtrem.c
new file mode 100644
index 00000000000..f5fcd09bcdd
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-sqrtrem.c
@@ -0,0 +1,98 @@
+/* Test mpz_add, mpz_add_ui, mpz_cmp, mpz_cmp, mpz_mul, mpz_sqrtrem.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t x2;
+ mpz_t x, rem;
+ mpz_t temp, temp2;
+ mp_size_t x2_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (x2);
+ mpz_init (x);
+ mpz_init (rem);
+ mpz_init (temp);
+ mpz_init (temp2);
+
+ for (i = 0; i < reps; i++)
+ {
+ x2_size = urandom () % SIZE;
+
+ mpz_random2 (x2, x2_size);
+
+ mpz_sqrtrem (x, rem, x2);
+ mpz_mul (temp, x, x);
+
+ /* Is square of result > argument? */
+ if (mpz_cmp (temp, x2) > 0)
+ dump_abort (x2, x, rem);
+
+ mpz_add_ui (temp2, x, 1);
+ mpz_mul (temp2, temp2, temp2);
+
+ /* Is square of (result + 1) <= argument? */
+ if (mpz_cmp (temp2, x2) <= 0)
+ dump_abort (x2, x, rem);
+
+ mpz_add (temp2, temp, rem);
+
+ /* Is the remainder wrong? */
+ if (mpz_cmp (x2, temp2) != 0)
+ dump_abort (x2, x, rem);
+ }
+
+ exit (0);
+}
+
+dump_abort (x2, x, rem)
+ mpz_t x2, x, rem;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "x2 = "); debug_mp (x2, -16);
+ fprintf (stderr, "x = "); debug_mp (x, -16);
+ fprintf (stderr, "remainder = "); debug_mp (rem, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-tdiv.c b/gnu/lib/libgmp/mpz/tests/t-tdiv.c
new file mode 100644
index 00000000000..d646ed8c59d
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-tdiv.c
@@ -0,0 +1,118 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr, mpz_tdiv_q,
+ mpz_tdiv_r, mpz_mul.
+
+Copyright (C) 1991, 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend, divisor;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size, divisor_size;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (divisor);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (divisor, divisor_size);
+ if (mpz_cmp_ui (divisor, 0) == 0)
+ continue;
+
+ mpz_tdiv_qr (quotient, remainder, dividend, divisor);
+ mpz_tdiv_q (quotient2, dividend, divisor);
+ mpz_tdiv_r (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != ((mpz_cmp_ui (dividend, 0) ^ mpz_cmp_ui (divisor, 0)) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (temp, divisor);
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp (remainder, temp) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend, divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = "); debug_mp (divisor, -16);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}
diff --git a/gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c b/gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c
new file mode 100644
index 00000000000..8d73b110816
--- /dev/null
+++ b/gnu/lib/libgmp/mpz/tests/t-tdiv_ui.c
@@ -0,0 +1,117 @@
+/* Test mpz_abs, mpz_add, mpz_cmp, mpz_cmp_ui, mpz_tdiv_qr_ui, mpz_tdiv_q_ui,
+ mpz_tdiv_r_ui, mpz_mul_ui.
+
+Copyright (C) 1993, 1994, 1996 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 Library General Public License as published by
+the Free Software Foundation; either version 2 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 Library General Public
+License for more details.
+
+You should have received a copy of the GNU Library General Public License
+along with the GNU MP Library; see the file COPYING.LIB. If not, write to
+the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+MA 02111-1307, USA. */
+
+#include <stdio.h>
+#include "gmp.h"
+#include "gmp-impl.h"
+#include "urandom.h"
+
+void debug_mp ();
+
+#ifndef SIZE
+#define SIZE 16
+#endif
+
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ mpz_t dividend;
+ mpz_t quotient, remainder;
+ mpz_t quotient2, remainder2;
+ mpz_t temp;
+ mp_size_t dividend_size;
+ mp_limb_t divisor;
+ int i;
+ int reps = 100000;
+
+ if (argc == 2)
+ reps = atoi (argv[1]);
+
+ mpz_init (dividend);
+ mpz_init (quotient);
+ mpz_init (remainder);
+ mpz_init (quotient2);
+ mpz_init (remainder2);
+ mpz_init (temp);
+
+ for (i = 0; i < reps; i++)
+ {
+ dividend_size = urandom () % SIZE - SIZE/2;
+ mpz_random2 (dividend, dividend_size);
+
+ divisor = urandom ();
+ if (divisor == 0)
+ continue;
+
+ mpz_tdiv_qr_ui (quotient, remainder, dividend, divisor);
+ mpz_tdiv_q_ui (quotient2, dividend, divisor);
+ mpz_tdiv_r_ui (remainder2, dividend, divisor);
+
+ /* First determine that the quotients and remainders computed
+ with different functions are equal. */
+ if (mpz_cmp (quotient, quotient2) != 0)
+ dump_abort (dividend, divisor);
+ if (mpz_cmp (remainder, remainder2) != 0)
+ dump_abort (dividend, divisor);
+
+ /* Check if the sign of the quotient is correct. */
+ if (mpz_cmp_ui (quotient, 0) != 0)
+ if ((mpz_cmp_ui (quotient, 0) < 0)
+ != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ /* Check if the remainder has the same sign as the dividend
+ (quotient rounded towards 0). */
+ if (mpz_cmp_ui (remainder, 0) != 0)
+ if ((mpz_cmp_ui (remainder, 0) < 0) != (mpz_cmp_ui (dividend, 0) < 0))
+ dump_abort (dividend, divisor);
+
+ mpz_mul_ui (temp, quotient, divisor);
+ mpz_add (temp, temp, remainder);
+ if (mpz_cmp (temp, dividend) != 0)
+ dump_abort (dividend, divisor);
+
+ mpz_abs (remainder, remainder);
+ if (mpz_cmp_ui (remainder, divisor) >= 0)
+ dump_abort (dividend, divisor);
+ }
+
+ exit (0);
+}
+
+dump_abort (dividend, divisor)
+ mpz_t dividend;
+ mp_limb_t divisor;
+{
+ fprintf (stderr, "ERROR\n");
+ fprintf (stderr, "dividend = "); debug_mp (dividend, -16);
+ fprintf (stderr, "divisor = %lX\n", divisor);
+ abort();
+}
+
+void
+debug_mp (x, base)
+ mpz_t x;
+{
+ mpz_out_str (stderr, base, x); fputc ('\n', stderr);
+}