Coverage Report

Created: 2025-03-09 06:52

/src/gmp-6.2.1/mpz/nextprime.c
Line
Count
Source (jump to first uncovered line)
1
/* mpz_nextprime(p,t) - compute the next prime > t and store that in p.
2
3
Copyright 1999-2001, 2008, 2009, 2012 Free Software Foundation, Inc.
4
5
Contributed to the GNU project by Niels Möller and Torbjorn Granlund.
6
7
This file is part of the GNU MP Library.
8
9
The GNU MP Library is free software; you can redistribute it and/or modify
10
it under the terms of either:
11
12
  * the GNU Lesser General Public License as published by the Free
13
    Software Foundation; either version 3 of the License, or (at your
14
    option) any later version.
15
16
or
17
18
  * the GNU General Public License as published by the Free Software
19
    Foundation; either version 2 of the License, or (at your option) any
20
    later version.
21
22
or both in parallel, as here.
23
24
The GNU MP Library is distributed in the hope that it will be useful, but
25
WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
26
or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
27
for more details.
28
29
You should have received copies of the GNU General Public License and the
30
GNU Lesser General Public License along with the GNU MP Library.  If not,
31
see https://www.gnu.org/licenses/.  */
32
33
#include "gmp-impl.h"
34
#include "longlong.h"
35
36
static const unsigned char primegap[] =
37
{
38
  2,2,4,2,4,2,4,6,2,6,4,2,4,6,6,2,6,4,2,6,4,6,8,4,2,4,2,4,14,4,6,
39
  2,10,2,6,6,4,6,6,2,10,2,4,2,12,12,4,2,4,6,2,10,6,6,6,2,6,4,2,10,14,4,2,
40
  4,14,6,10,2,4,6,8,6,6,4,6,8,4,8,10,2,10,2,6,4,6,8,4,2,4,12,8,4,8,4,6,
41
  12,2,18,6,10,6,6,2,6,10,6,6,2,6,6,4,2,12,10,2,4,6,6,2,12,4,6,8,10,8,10,8,
42
  6,6,4,8,6,4,8,4,14,10,12,2,10,2,4,2,10,14,4,2,4,14,4,2,4,20,4,8,10,8,4,6,
43
  6,14,4,6,6,8,6,12
44
};
45
46
1.63k
#define NUMBER_OF_PRIMES 167
47
48
void
49
mpz_nextprime (mpz_ptr p, mpz_srcptr n)
50
1.28k
{
51
1.28k
  unsigned short *moduli;
52
1.28k
  unsigned long difference;
53
1.28k
  int i;
54
1.28k
  unsigned prime_limit;
55
1.28k
  unsigned long prime;
56
1.28k
  mp_size_t pn;
57
1.28k
  mp_bitcnt_t nbits;
58
1.28k
  unsigned incr;
59
1.28k
  TMP_SDECL;
60
61
  /* First handle tiny numbers */
62
1.28k
  if (mpz_cmp_ui (n, 2) < 0)
63
96
    {
64
96
      mpz_set_ui (p, 2);
65
96
      return;
66
96
    }
67
1.19k
  mpz_add_ui (p, n, 1);
68
1.19k
  mpz_setbit (p, 0);
69
70
1.19k
  if (mpz_cmp_ui (p, 7) <= 0)
71
1
    return;
72
73
1.19k
  pn = SIZ(p);
74
1.19k
  MPN_SIZEINBASE_2EXP(nbits, PTR(p), pn, 1);
75
1.19k
  if (nbits / 2 >= NUMBER_OF_PRIMES)
76
438
    prime_limit = NUMBER_OF_PRIMES - 1;
77
754
  else
78
754
    prime_limit = nbits / 2;
79
80
1.19k
  TMP_SMARK;
81
82
  /* Compute residues modulo small odd primes */
83
1.19k
  moduli = TMP_SALLOC_TYPE (prime_limit, unsigned short);
84
85
1.19k
  for (;;)
86
1.19k
    {
87
      /* FIXME: Compute lazily? */
88
1.19k
      prime = 3;
89
129k
      for (i = 0; i < prime_limit; i++)
90
128k
  {
91
128k
    moduli[i] = mpz_tdiv_ui (p, prime);
92
128k
    prime += primegap[i];
93
128k
  }
94
95
100k
#define INCR_LIMIT 0x10000  /* deep science */
96
97
100k
      for (difference = incr = 0; incr < INCR_LIMIT; difference += 2)
98
100k
  {
99
    /* First check residues */
100
100k
    prime = 3;
101
3.23M
    for (i = 0; i < prime_limit; i++)
102
3.22M
      {
103
3.22M
        unsigned r;
104
        /* FIXME: Reduce moduli + incr and store back, to allow for
105
     division-free reductions.  Alternatively, table primes[]'s
106
     inverses (mod 2^16).  */
107
3.22M
        r = (moduli[i] + incr) % prime;
108
3.22M
        prime += primegap[i];
109
110
3.22M
        if (r == 0)
111
83.5k
    goto next;
112
3.22M
      }
113
114
17.3k
    mpz_add_ui (p, p, difference);
115
17.3k
    difference = 0;
116
117
    /* Miller-Rabin test */
118
17.3k
    if (mpz_millerrabin (p, 25))
119
1.19k
      goto done;
120
99.6k
  next:;
121
99.6k
    incr += 2;
122
99.6k
  }
123
0
      mpz_add_ui (p, p, difference);
124
0
      difference = 0;
125
0
    }
126
1.19k
 done:
127
1.19k
  TMP_SFREE;
128
1.19k
}