1 /*
2 Authored 2015 by Daniel S. Roche; US Government work in the public domain.
3
4 This file is part of FLINT.
5
6 FLINT is free software: you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License (LGPL) as published
8 by the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version. See <https://www.gnu.org/licenses/>.
10 */
11
12 #include <gmp.h>
13 #include "flint.h"
14 #include "fmpz.h"
15 #include "ulong_extras.h"
16
fmpz_nextprime(fmpz_t res,const fmpz_t n,int proved)17 void fmpz_nextprime(fmpz_t res, const fmpz_t n, int proved)
18 {
19 if (fmpz_sgn(n) <= 0)
20 {
21 fmpz_set_ui(res, UWORD(2));
22 return;
23 }
24 else if (COEFF_IS_MPZ(*n))
25 {
26 /* n is big */
27 __mpz_struct *res_mpz = _fmpz_promote(res);
28 mpz_nextprime(res_mpz, COEFF_TO_PTR(*n));
29 }
30 else if (FLINT_BIT_COUNT(*n) < FLINT_BITS - 2)
31 {
32 /* n and res will both be small */
33 _fmpz_demote(res);
34 *res = n_nextprime(*n, proved);
35 return;
36 }
37 else if (res != n)
38 {
39 /* n is small, but res might not be */
40 mpz_t temp_n;
41 __mpz_struct *res_mpz = _fmpz_promote(res);
42 flint_mpz_init_set_ui(temp_n, *n);
43 mpz_nextprime(res_mpz, temp_n);
44 _fmpz_demote_val(res);
45 mpz_clear(temp_n);
46 }
47 else
48 {
49 /* same as above case, but need to handle aliasing here. */
50 __mpz_struct *res_mpz = _fmpz_promote_val(res);
51 mpz_nextprime(res_mpz, res_mpz);
52 _fmpz_demote_val(res);
53 }
54
55 if (proved)
56 {
57 if (!fmpz_is_prime(res))
58 {
59 /* Keep searching. No big penalty for recursion here because this
60 * will almost never happen.
61 */
62 fmpz_nextprime(res, res, proved);
63 }
64 }
65 }
66