diff options
author | Marco Bodrato <bodrato@mail.dm.unipi.it> | 2018-04-26 23:31:31 +0200 |
---|---|---|
committer | Marco Bodrato <bodrato@mail.dm.unipi.it> | 2018-04-26 23:31:31 +0200 |
commit | a13886d572971c4bd8e2b5cac19fa16b6aa66d9d (patch) | |
tree | 27605b660e1ee9fd37a744a7ddc8c296a46abb2b /mini-gmp/tests | |
parent | 27e32ee310114371cf6c205b1827e6b36dc605ba (diff) | |
download | gmp-a13886d572971c4bd8e2b5cac19fa16b6aa66d9d.tar.gz |
mini-mpq and its tests
Diffstat (limited to 'mini-gmp/tests')
-rw-r--r-- | mini-gmp/tests/Makefile | 7 | ||||
-rw-r--r-- | mini-gmp/tests/t-mpq_addsub.c | 164 | ||||
-rw-r--r-- | mini-gmp/tests/t-mpq_muldiv.c | 160 | ||||
-rw-r--r-- | mini-gmp/tests/t-mpq_muldiv_2exp.c | 138 | ||||
-rw-r--r-- | mini-gmp/tests/testutils.c | 1 |
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; |