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