summaryrefslogtreecommitdiff
path: root/mini-gmp/tests
diff options
context:
space:
mode:
authorMarco Bodrato <bodrato@mail.dm.unipi.it>2018-04-26 23:31:31 +0200
committerMarco Bodrato <bodrato@mail.dm.unipi.it>2018-04-26 23:31:31 +0200
commita13886d572971c4bd8e2b5cac19fa16b6aa66d9d (patch)
tree27605b660e1ee9fd37a744a7ddc8c296a46abb2b /mini-gmp/tests
parent27e32ee310114371cf6c205b1827e6b36dc605ba (diff)
downloadgmp-a13886d572971c4bd8e2b5cac19fa16b6aa66d9d.tar.gz
mini-mpq and its tests
Diffstat (limited to 'mini-gmp/tests')
-rw-r--r--mini-gmp/tests/Makefile7
-rw-r--r--mini-gmp/tests/t-mpq_addsub.c164
-rw-r--r--mini-gmp/tests/t-mpq_muldiv.c160
-rw-r--r--mini-gmp/tests/t-mpq_muldiv_2exp.c138
-rw-r--r--mini-gmp/tests/testutils.c1
5 files changed, 467 insertions, 3 deletions
diff --git a/mini-gmp/tests/Makefile b/mini-gmp/tests/Makefile
index e4191c59f..7440729e1 100644
--- a/mini-gmp/tests/Makefile
+++ b/mini-gmp/tests/Makefile
@@ -30,7 +30,8 @@ LIBS = -lgmp -lm -lmcheck
CHECK_PROGRAMS = t-add t-sub t-mul t-invert t-div t-div_2exp \
t-double t-cmp_d t-gcd t-lcm t-import t-comb t-signed \
t-sqrt t-root t-powm t-logops t-bitops t-scan t-str \
- t-reuse t-aorsmul t-limbs t-cong t-pprime_p
+ t-reuse t-aorsmul t-limbs t-cong t-pprime_p \
+ t-mpq_addsub t-mpq_muldiv t-mpq_muldiv_2exp
# Default TESTS to all tests, allowing overriding TESTS for building tests
# without running them.
TESTS = $(CHECK_PROGRAMS)
@@ -48,10 +49,10 @@ clean:
# Keep object files
.PRECIOUS: %.o
-%.o: %.c $(MINI_GMP_DIR)/mini-gmp.h hex-random.h mini-random.h
+%.o: %.c $(MINI_GMP_DIR)/mini-gmp.h $(MINI_GMP_DIR)/mini-mpq.h hex-random.h mini-random.h
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< -o $@
-testutils.o: $(MINI_GMP_DIR)/mini-gmp.c
+testutils.o: $(MINI_GMP_DIR)/mini-gmp.c $(MINI_GMP_DIR)/mini-mpq.c
%: %.o $(MISC_OBJS)
$(CC) $(CFLAGS) $(LDFLAGS) $^ $(LIBS) -o $@
diff --git a/mini-gmp/tests/t-mpq_addsub.c b/mini-gmp/tests/t-mpq_addsub.c
new file mode 100644
index 000000000..3cd53f13c
--- /dev/null
+++ b/mini-gmp/tests/t-mpq_addsub.c
@@ -0,0 +1,164 @@
+/*
+
+Copyright 2012, 2013, 2018 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 https://www.gnu.org/licenses/. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+#include "../mini-mpq.h"
+
+#define MAXBITS 300
+#define COUNT 10000
+
+static void
+_mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
+{
+ if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
+ {
+ mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
+ }
+ else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
+ {
+ mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
+ }
+ else
+ {
+ mpq_set_num (q, n);
+ mpq_set_den (q, d);
+ }
+ mpq_canonicalize (q);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, q, r, c;
+ mpq_t rr, ii, ff;
+ int tst;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (r);
+ mpz_init (q);
+ mpz_init (c);
+ mpq_init (rr);
+ mpq_init (ff);
+ mpq_init (ii);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op4 (OP_TDIV, MAXBITS, a, b, q, r);
+
+ _mpq_set_zz (rr, a, b);
+ _mpq_set_zz (ff, r, b);
+
+ mpq_set_z (ii, q);
+
+ mpz_set_q (c, rr);
+ if (mpz_cmp (c, q))
+ {
+ fprintf (stderr, "mpz_set_q failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("c", c);
+ dump ("q", q);
+ abort ();
+ }
+
+ if ((mpz_sgn (r) != 0) ^ (mpz_cmp_ui (mpq_denref (rr), 1) != 0))
+ {
+ fprintf (stderr, "mpq_canonicalize failed:\n");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", r);
+ dump ("D", mpq_denref (rr));
+ abort ();
+ }
+
+ if (i & 1)
+ {
+ if (mpz_fits_slong_p (q))
+ tst = mpq_cmp_si (rr, mpz_get_si (q), 1);
+ else if (mpz_fits_ulong_p (q))
+ tst = mpq_cmp_ui (rr, mpz_get_ui (q), 1);
+ else
+ tst = mpq_cmp_z (rr, q);
+ if (mpz_sgn (b) < 0)
+ tst = - tst;
+ if ((tst != mpz_sgn (r)) && ((tst < 0 && mpz_sgn (r) >= 0) || (tst > 0 && mpz_sgn (r) <= 0)))
+ {
+ fprintf (stderr, "mpq_cmp ii failed: %i %i\n", tst, mpz_sgn (r));
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", r);
+ dump ("q", q);
+ abort ();
+ }
+ }
+ else
+ {
+ if (mpz_fits_ulong_p (b) && mpz_fits_slong_p (r))
+ tst = mpq_cmp_si (rr, mpz_get_si (r), mpz_get_ui (b));
+ else if (mpz_fits_ulong_p (b) && mpz_fits_ulong_p (r))
+ tst = mpq_cmp_ui (rr, mpz_get_ui (r), mpz_get_ui (b));
+ else
+ tst = mpq_cmp (rr, ff);
+ if ((tst != mpz_sgn (q)) && ((tst < 0 && mpz_sgn (q) >= 0) || (tst > 0 && mpz_sgn (q) <= 0)))
+ {
+ fprintf (stderr, "mpq_cmp ff failed: %i %i\n", tst, mpz_sgn (q));
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", r);
+ dump ("q", q);
+ abort ();
+ }
+ }
+
+ if (i & 1)
+ {
+ mpq_sub (rr, rr, ff);
+ }
+ else
+ {
+ mpq_neg (ff, ff);
+ mpq_add (rr, ff, rr);
+ }
+
+ if (!mpq_equal (ii, rr))
+ {
+ fprintf (stderr, "mpq_%s failed:\n", (i & 1) ? "sub" : "add");
+ dump ("a", a);
+ dump ("b", b);
+ dump ("r", r);
+ dump ("q", q);
+ abort ();
+ }
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (r);
+ mpz_clear (q);
+ mpz_clear (c);
+ mpq_clear (rr);
+ mpq_clear (ff);
+ mpq_clear (ii);
+}
diff --git a/mini-gmp/tests/t-mpq_muldiv.c b/mini-gmp/tests/t-mpq_muldiv.c
new file mode 100644
index 000000000..03282da62
--- /dev/null
+++ b/mini-gmp/tests/t-mpq_muldiv.c
@@ -0,0 +1,160 @@
+/*
+
+Copyright 2012, 2013, 2018 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 https://www.gnu.org/licenses/. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+#include "../mini-mpq.h"
+
+#define MAXBITS 300
+#define COUNT 10000
+
+static void
+_mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
+{
+ if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
+ {
+ mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
+ }
+ else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
+ {
+ mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
+ }
+ else
+ {
+ mpq_set_num (q, n);
+ mpq_set_den (q, d);
+ }
+ mpq_canonicalize (q);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t an, bn, rn, ad, bd, rd;
+ mpq_t aq, bq, refq, resq;
+ int tst;
+
+ mpz_init (an);
+ mpz_init (bn);
+ mpz_init (rn);
+ mpz_init (ad);
+ mpz_init (bd);
+ mpz_init (rd);
+ mpq_init (aq);
+ mpq_init (bq);
+ mpq_init (refq);
+ mpq_init (resq);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ mini_random_op3 (OP_MUL, MAXBITS, an, bn, rn);
+ do {
+ mini_random_op3 (OP_MUL, MAXBITS, ad, bd, rd);
+ } while (mpz_sgn (rd) == 0);
+
+ _mpq_set_zz (aq, an, ad);
+ _mpq_set_zz (bq, bn, bd);
+ _mpq_set_zz (refq, rn, rd);
+
+ mpq_mul (resq, aq, bq);
+ if (!mpq_equal (resq, refq))
+ {
+ fprintf (stderr, "mpq_mul failed [%i]:\n", i);
+ dump ("an", an);
+ dump ("ad", ad);
+ dump ("bn", bn);
+ dump ("bd", bd);
+ dump ("refn", rn);
+ dump ("refd", rd);
+ dump ("resn", mpq_numref (resq));
+ dump ("resd", mpq_denref (resq));
+ abort ();
+ }
+
+ if (mpq_sgn (refq) != 0)
+ {
+ mpq_set_ui (resq, ~6, 8);
+ mpq_inv (aq, aq);
+ mpq_div (resq, aq, bq);
+ mpq_inv (resq, resq);
+ if (!mpq_equal (resq, refq))
+ {
+ fprintf (stderr, "mpq_div failed [%i]:\n", i);
+ dump ("an", an);
+ dump ("ad", ad);
+ dump ("bn", bn);
+ dump ("bd", bd);
+ dump ("refn", rn);
+ dump ("refd", rd);
+ dump ("resn", mpq_numref (resq));
+ dump ("resd", mpq_denref (resq));
+ abort ();
+ }
+
+ mpq_swap (bq, aq);
+ mpq_div (resq, aq, bq);
+ if (!mpq_equal (resq, refq))
+ {
+ fprintf (stderr, "mpq_swap failed [%i]:\n", i);
+ dump ("an", an);
+ dump ("ad", ad);
+ dump ("bn", bn);
+ dump ("bd", bd);
+ dump ("refn", rn);
+ dump ("refd", rd);
+ dump ("resn", mpq_numref (resq));
+ dump ("resd", mpq_denref (resq));
+ abort ();
+ }
+ }
+
+ mpq_set (resq, aq);
+ mpq_neg (bq, aq);
+ mpq_abs (refq, aq);
+ if (mpq_equal (refq, resq))
+ mpq_add (resq, refq, bq);
+ else
+ mpq_add (resq, refq, resq);
+ mpq_set_ui (refq, 0, 1);
+ if (!mpq_equal (resq, refq))
+ {
+ fprintf (stderr, "mpq_abs failed [%i]:\n", i);
+ dump ("an", an);
+ dump ("ad", ad);
+ dump ("resn", mpq_numref (resq));
+ dump ("resd", mpq_denref (resq));
+ abort ();
+ }
+ }
+
+ mpz_clear (an);
+ mpz_clear (bn);
+ mpz_clear (rn);
+ mpz_clear (ad);
+ mpz_clear (bd);
+ mpz_clear (rd);
+ mpq_clear (aq);
+ mpq_clear (bq);
+ mpq_clear (refq);
+ mpq_clear (resq);
+}
diff --git a/mini-gmp/tests/t-mpq_muldiv_2exp.c b/mini-gmp/tests/t-mpq_muldiv_2exp.c
new file mode 100644
index 000000000..fe78f3b35
--- /dev/null
+++ b/mini-gmp/tests/t-mpq_muldiv_2exp.c
@@ -0,0 +1,138 @@
+/*
+
+Copyright 2012, 2013, 2018 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 https://www.gnu.org/licenses/. */
+
+#include <assert.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "testutils.h"
+#include "../mini-mpq.h"
+
+#define MAXBITS 300
+#define COUNT 10000
+
+static void
+_mpq_set_zz (mpq_t q, mpz_t n, mpz_t d)
+{
+ if (mpz_fits_ulong_p (d) && mpz_fits_slong_p (n))
+ {
+ mpq_set_si (q, mpz_get_si (n), mpz_get_ui (d));
+ }
+ else if (mpz_fits_ulong_p (d) && mpz_fits_ulong_p (n))
+ {
+ mpq_set_ui (q, mpz_get_ui (n), mpz_get_ui (d));
+ }
+ else
+ {
+ mpq_set_num (q, n);
+ mpq_set_den (q, d);
+ }
+ mpq_canonicalize (q);
+}
+
+void
+testmain (int argc, char **argv)
+{
+ unsigned i;
+ mpz_t a, b, t;
+ mpq_t aq, rq, tq;
+ mp_bitcnt_t e;
+ long int e2, t1, t2;
+
+ mpz_init (a);
+ mpz_init (b);
+ mpz_init (t);
+ mpq_init (aq);
+ mpq_init (rq);
+ mpq_init (tq);
+
+ for (i = 0; i < COUNT; i++)
+ {
+ do {
+ mini_random_bit_op (OP_COMBIT, MAXBITS, a, &e, b);
+ } while (mpz_sgn (a) == 0 || mpz_sgn (b) == 0);
+
+ _mpq_set_zz (aq, a, b);
+ e2 = mpz_scan1 (a, 0);
+ e2-= mpz_scan1 (b, 0);
+
+ mpq_mul_2exp (rq, aq, e);
+ t1 = mpz_scan1 (mpq_numref (rq), 0);
+ t2 = mpz_scan1 (mpq_denref (rq), 0);
+ mpq_neg (tq, rq);
+ mpq_div (tq, aq, tq);
+ mpq_get_den (t, tq);
+
+ if (e2 + e != t1 - t2 || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e
+ || mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_si (mpq_numref (tq), -1) != 0)
+ {
+ fprintf (stderr, "mpq_mul_2exp failed: %lu\n", e);
+ dump ("na", a);
+ dump ("da", b);
+ dump ("nr", mpq_numref (rq));
+ dump ("dr", mpq_denref (rq));
+ abort ();
+ }
+
+ mpq_div_2exp (rq, aq, e);
+ t1 = mpz_scan1 (mpq_numref (rq), 0);
+ t2 = mpz_scan1 (mpq_denref (rq), 0);
+ mpq_div (aq, aq, rq);
+ mpq_get_num (t, aq);
+
+ if (e2 != t1 - t2 + e || (t2 != 0 && t1 != 0) || mpz_scan1 (t, 0) != e
+ || mpz_sizeinbase (t, 2) - 1 != e || mpz_cmp_ui (mpq_denref (aq), 1) != 0)
+ {
+ fprintf (stderr, "mpq_div_2exp failed: %lu\n", e);
+ fprintf (stderr, "%li %li %lu %lu\n", e2, t2, mpz_scan1 (t, 0), mpz_sizeinbase (t, 2));
+ dump ("na", a);
+ dump ("da", b);
+ dump ("nr", mpq_numref (rq));
+ dump ("dr", mpq_denref (rq));
+ abort ();
+ }
+
+ mpq_set_ui (aq, 0, 1);
+ mpq_set_ui (rq, 6, 7);
+ mpq_set (tq, aq);
+ mpq_div_2exp (rq, aq, e);
+
+ if (!mpq_equal (tq, rq))
+ {
+ fprintf (stderr, "mpq_div_2exp failed on zero: %lu\n", e);
+ abort ();
+ }
+
+ mpq_set_ui (rq, 7, 6);
+ mpq_mul_2exp (rq, aq, e);
+
+ if (!mpq_equal (rq, tq))
+ {
+ fprintf (stderr, "mpq_mul_2exp failed on zero: %lu\n", e);
+ abort ();
+ }
+ }
+
+ mpz_clear (a);
+ mpz_clear (b);
+ mpz_clear (t);
+ mpq_clear (aq);
+ mpq_clear (rq);
+ mpq_clear (tq);
+}
diff --git a/mini-gmp/tests/testutils.c b/mini-gmp/tests/testutils.c
index b49bd2267..ff4a4a178 100644
--- a/mini-gmp/tests/testutils.c
+++ b/mini-gmp/tests/testutils.c
@@ -22,6 +22,7 @@ the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */
/* Include it here, so we we could tweak, e.g., how MPZ_REALLOC
works. */
#include "../mini-gmp.c"
+#include "../mini-mpq.c"
static size_t total_alloc = 0;