From 15b9717d18fd9ae54c2f243f51838230df6cbf34 Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Thu, 9 May 2019 09:20:23 -0700 Subject: [PATCH 1/3] Extra git files --- .bootstrap | 15 +++++++++++++++ .editorconfig | 7 +++++++ .gitignore | 8 ++++++++ 3 files changed, 30 insertions(+) create mode 100755 .bootstrap create mode 100644 .editorconfig create mode 100644 .gitignore diff --git a/.bootstrap b/.bootstrap new file mode 100755 index 0000000..3415fb3 --- /dev/null +++ b/.bootstrap @@ -0,0 +1,15 @@ +#! /bin/sh + +# We need to remove the "cache", else things are not regenerated properly +rm -rf autom4te.cache + +# for warnings, add: -v -W all +autoreconf -i -s +# aclocal && libtoolize && autoconf && autoheader && automake -a + +cat >doc/version.texi < Date: Sat, 18 May 2019 15:03:42 -0700 Subject: [PATCH 2/3] Add nth_prime_ui impl, tests, and docs. --- Makefile.am | 3 +- doc/gmp.texi | 5 ++ gmp-h.in | 3 + mpz/nthprime_ui.c | 68 ++++++++++++++++++++ tests/mpz/Makefile.am | 3 +- tests/mpz/t-nthprime_ui.c | 127 ++++++++++++++++++++++++++++++++++++++ 6 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 mpz/nthprime_ui.c create mode 100644 tests/mpz/t-nthprime_ui.c diff --git a/Makefile.am b/Makefile.am index 2709ec0..ee428af 100644 --- a/Makefile.am +++ b/Makefile.am @@ -200,7 +200,8 @@ MPZ_OBJECTS = mpz/abs$U.lo mpz/add$U.lo mpz/add_ui$U.lo \ mpz/millerrabin$U.lo mpz/mod$U.lo mpz/mul$U.lo mpz/mul_2exp$U.lo \ mpz/mul_si$U.lo mpz/mul_ui$U.lo \ mpz/n_pow_ui$U.lo mpz/neg$U.lo mpz/nextprime$U.lo \ - mpz/out_raw$U.lo mpz/out_str$U.lo mpz/perfpow$U.lo mpz/perfsqr$U.lo \ + mpz/nthprime_ui$U.lo mpz/out_raw$U.lo mpz/out_str$U.lo \ + mpz/perfpow$U.lo mpz/perfsqr$U.lo \ mpz/popcount$U.lo mpz/pow_ui$U.lo mpz/powm$U.lo mpz/powm_sec$U.lo \ mpz/powm_ui$U.lo mpz/primorial_ui$U.lo \ mpz/pprime_p$U.lo mpz/random$U.lo mpz/random2$U.lo \ diff --git a/doc/gmp.texi b/doc/gmp.texi index 60c2634..6dbcfa8 100644 --- a/doc/gmp.texi +++ b/doc/gmp.texi @@ -3565,6 +3565,11 @@ practical purposes it's adequate, the chance of a composite passing will be extremely small. @end deftypefun +@deftypefun void mpz_nthprime_ui (mpz_t @var{rop}, unsigned long int @var{n}) +@cindex Nth prime function +Set @var{rop} to the @var{n}th prime. @var{rop} will be 2 if @var{n} is zero. +@end deftypefun + @c mpz_prime_p not implemented as of gmp 3.0. @c @deftypefun int mpz_prime_p (const mpz_t @var{n}) diff --git a/gmp-h.in b/gmp-h.in index f448b4e..c447a48 100644 --- a/gmp-h.in +++ b/gmp-h.in @@ -947,6 +947,9 @@ __GMP_DECLSPEC void mpz_neg (mpz_ptr, mpz_srcptr); #define mpz_nextprime __gmpz_nextprime __GMP_DECLSPEC void mpz_nextprime (mpz_ptr, mpz_srcptr); +#define mpz_nthprime_ui __gmpz_nthprime_ui +__GMP_DECLSPEC void mpz_nthprime_ui (mpz_ptr, unsigned long int); + #define mpz_out_raw __gmpz_out_raw #ifdef _GMP_H_HAVE_FILE __GMP_DECLSPEC size_t mpz_out_raw (FILE *, mpz_srcptr); diff --git a/mpz/nthprime_ui.c b/mpz/nthprime_ui.c new file mode 100644 index 0000000..a11cbe4 --- /dev/null +++ b/mpz/nthprime_ui.c @@ -0,0 +1,68 @@ +/* mpz_nthprime_ui(p, n) - compute the nth prime and store it in p. + +Copyright 2019 Free Software Foundation, Inc. + +Contributed to the GNU project by Seth Troisi + +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 either: + + * 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. + +or + + * the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any + later version. + +or both in parallel, as here. + +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 General Public License +for more details. + +You should have received copies of the GNU General Public License and the +GNU Lesser General Public License along with the GNU MP Library. If not, +see https://www.gnu.org/licenses/. */ + +#include "gmp-impl.h" +#include "longlong.h" + + +/* Enhancements: + + - Use sieve for smallish n + - Use precomputed lookup values as started point + - Implement a more modern algorithm */ + + +void +mpz_nthprime_ui (mpz_ptr p, unsigned long n) +{ + /* UNDERSTAND: this condition appears for mpz_primorial_ui */ + ASSERT (n <= GMP_NUMB_MAX); + + /* Allocate 1 LIMBS */ + MPZ_NEWALLOC (p, 1); + + PTR (p)[0] = 1; + SIZ (p) = 1; + + if (n <= 1) + { + /* nth_prime(p, 0) = 2 */ + PTR (p)[0] = 2; + return; + } + + /* Simple proof of concept implementation, soon to be replaced. */ + while (n-- > 0) + { + mpz_nextprime(p, p); + } +} diff --git a/tests/mpz/Makefile.am b/tests/mpz/Makefile.am index 6a56eda..a911608 100644 --- a/tests/mpz/Makefile.am +++ b/tests/mpz/Makefile.am @@ -30,7 +30,8 @@ check_PROGRAMS = reuse t-addsub t-cmp t-mul t-mul_i t-tdiv t-tdiv_ui t-fdiv \ t-fac_ui t-mfac_uiui t-primorial_ui t-fib_ui t-lucnum_ui t-scan t-fits \ t-divis t-divis_2exp t-cong t-cong_2exp t-sizeinbase t-set_str \ t-aorsmul t-cmp_d t-cmp_si t-hamdist t-oddeven t-popcount t-set_f \ - t-io_raw t-import t-export t-pprime_p t-nextprime t-remove t-limbs + t-io_raw t-import t-export t-pprime_p t-nextprime t-remove t-limbs \ + t-nthprime_ui TESTS = $(check_PROGRAMS) diff --git a/tests/mpz/t-nthprime_ui.c b/tests/mpz/t-nthprime_ui.c new file mode 100644 index 0000000..88fc214 --- /dev/null +++ b/tests/mpz/t-nthprime_ui.c @@ -0,0 +1,127 @@ +/* Test mpz_nthprime_ui. + +Copyright 2019 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 +#include +#include "gmp-impl.h" +#include "tests.h" + + +/* Verify nth_prime(n) = want and isprime(want). */ +void +check_one (long n, long want) { + mpz_t got; + mpz_init(got); + + mpz_nthprime_ui(got, n); + MPZ_CHECK_FORMAT (got); + + if (mpz_cmp_si(got, want) != 0) + { + printf ("mpz_nthprime wrong\n"); + printf (" n=%lu\n", n); + printf (" got="); mpz_out_str (stdout, 10, got); printf ("\n"); + printf (" want=%lu\n", want); + abort(); + } + + if (!mpz_probab_prime_p(got, 25)) + { + printf ("mpz_nthprime_ui not prime\n"); + printf (" n=%lu\n", n); + printf (" p="); mpz_out_str (stdout, 10, got); printf ("\n"); + abort(); + } + + mpz_clear(got); +} + +void +check_data (void) +{ + static const struct { + int n; + long want; + } data[] = { + { 1, 2 }, + { 2, 3 }, + { 3, 5 }, + { 4, 7 }, + { 10, 29 }, + { 25, 97 }, + { 100, 541 }, + { 1000, 7919 }, + { 3141, 28843 }, + }; + + for (int i = 0; i < numberof (data); i++) + { + check_one(data[i].n, data[i].want); + } +} + +/* check nthprime(0) is correct */ +void +check_zero (void) +{ + mpz_t test; + mpz_init(test); + + mpz_nthprime_ui(test, 0); + if (mpz_cmp_si(test, 2)) + { + printf ("mpz_nthprime_ui(0) != 2\n"); + printf (" got "); mpz_out_str (stdout, 10, test); printf("\n"); + abort (); + } + + MPZ_CHECK_FORMAT (test); + + mpz_clear(test); +} + +/* check small n's. */ +void +check_small (void) +{ + mpz_t test; + mpz_init_set_ui(test, 1); + + for (int i = 1; i < 1000; i++) + { + mpz_nextprime(test, test); + + check_one(i, mpz_get_ui(test)); + } + + mpz_clear(test); +} + +int +main (int argc, char **argv) +{ + tests_start (); + + check_zero (); + check_small (); + check_data (); + + tests_end (); + exit (0); +} From a59a92d5968e693b207066d71dda3aafa060155c Mon Sep 17 00:00:00 2001 From: Seth Troisi Date: Wed, 22 May 2019 10:44:22 -0700 Subject: [PATCH 3/3] clang-format --- mpz/nthprime_ui.c | 4 +-- tests/mpz/t-nthprime_ui.c | 52 ++++++++++++++++++++++----------------- 2 files changed, 31 insertions(+), 25 deletions(-) diff --git a/mpz/nthprime_ui.c b/mpz/nthprime_ui.c index a11cbe4..12290be 100644 --- a/mpz/nthprime_ui.c +++ b/mpz/nthprime_ui.c @@ -33,14 +33,12 @@ see https://www.gnu.org/licenses/. */ #include "gmp-impl.h" #include "longlong.h" - /* Enhancements: - Use sieve for smallish n - Use precomputed lookup values as started point - Implement a more modern algorithm */ - void mpz_nthprime_ui (mpz_ptr p, unsigned long n) { @@ -63,6 +61,6 @@ mpz_nthprime_ui (mpz_ptr p, unsigned long n) /* Simple proof of concept implementation, soon to be replaced. */ while (n-- > 0) { - mpz_nextprime(p, p); + mpz_nextprime (p, p); } } diff --git a/tests/mpz/t-nthprime_ui.c b/tests/mpz/t-nthprime_ui.c index 88fc214..d45d167 100644 --- a/tests/mpz/t-nthprime_ui.c +++ b/tests/mpz/t-nthprime_ui.c @@ -19,43 +19,49 @@ the GNU MP Library test suite. If not, see https://www.gnu.org/licenses/. */ #include #include + #include "gmp-impl.h" #include "tests.h" - /* Verify nth_prime(n) = want and isprime(want). */ void -check_one (long n, long want) { +check_one (long n, long want) +{ mpz_t got; - mpz_init(got); + mpz_init (got); - mpz_nthprime_ui(got, n); + mpz_nthprime_ui (got, n); MPZ_CHECK_FORMAT (got); - if (mpz_cmp_si(got, want) != 0) + if (mpz_cmp_si (got, want) != 0) { printf ("mpz_nthprime wrong\n"); printf (" n=%lu\n", n); - printf (" got="); mpz_out_str (stdout, 10, got); printf ("\n"); + printf (" got="); + mpz_out_str (stdout, 10, got); + printf ("\n"); printf (" want=%lu\n", want); - abort(); + abort (); } - if (!mpz_probab_prime_p(got, 25)) + if (!mpz_probab_prime_p (got, 25)) { printf ("mpz_nthprime_ui not prime\n"); printf (" n=%lu\n", n); - printf (" p="); mpz_out_str (stdout, 10, got); printf ("\n"); - abort(); + printf (" p="); + mpz_out_str (stdout, 10, got); + printf ("\n"); + abort (); } - mpz_clear(got); + mpz_clear (got); } void check_data (void) { - static const struct { + static const struct + { int n; long want; } data[] = { @@ -72,7 +78,7 @@ check_data (void) for (int i = 0; i < numberof (data); i++) { - check_one(data[i].n, data[i].want); + check_one (data[i].n, data[i].want); } } @@ -81,19 +87,21 @@ void check_zero (void) { mpz_t test; - mpz_init(test); + mpz_init (test); - mpz_nthprime_ui(test, 0); - if (mpz_cmp_si(test, 2)) + mpz_nthprime_ui (test, 0); + if (mpz_cmp_si (test, 2)) { printf ("mpz_nthprime_ui(0) != 2\n"); - printf (" got "); mpz_out_str (stdout, 10, test); printf("\n"); + printf (" got "); + mpz_out_str (stdout, 10, test); + printf ("\n"); abort (); } MPZ_CHECK_FORMAT (test); - mpz_clear(test); + mpz_clear (test); } /* check small n's. */ @@ -101,16 +109,16 @@ void check_small (void) { mpz_t test; - mpz_init_set_ui(test, 1); + mpz_init_set_ui (test, 1); for (int i = 1; i < 1000; i++) { - mpz_nextprime(test, test); + mpz_nextprime (test, test); - check_one(i, mpz_get_ui(test)); + check_one (i, mpz_get_ui (test)); } - mpz_clear(test); + mpz_clear (test); } int