beta-0.89.2
[luatex.git] / source / libs / gmp / gmp-src / primesieve.c
blob569e4cecea9183790b19060f9ff352fbd193b4c8
1 /* primesieve (BIT_ARRAY, N) -- Fills the BIT_ARRAY with a mask for primes up to N.
3 Contributed to the GNU project by Marco Bodrato.
5 THE FUNCTION IN THIS FILE IS INTERNAL WITH A MUTABLE INTERFACE.
6 IT IS ONLY SAFE TO REACH IT THROUGH DOCUMENTED INTERFACES.
7 IN FACT, IT IS ALMOST GUARANTEED THAT IT WILL CHANGE OR
8 DISAPPEAR IN A FUTURE GNU MP RELEASE.
10 Copyright 2010-2012 Free Software Foundation, Inc.
12 This file is part of the GNU MP Library.
14 The GNU MP Library is free software; you can redistribute it and/or modify
15 it under the terms of either:
17 * the GNU Lesser General Public License as published by the Free
18 Software Foundation; either version 3 of the License, or (at your
19 option) any later version.
23 * the GNU General Public License as published by the Free Software
24 Foundation; either version 2 of the License, or (at your option) any
25 later version.
27 or both in parallel, as here.
29 The GNU MP Library is distributed in the hope that it will be useful, but
30 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
31 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
32 for more details.
34 You should have received copies of the GNU General Public License and the
35 GNU Lesser General Public License along with the GNU MP Library. If not,
36 see https://www.gnu.org/licenses/. */
38 #include "gmp.h"
39 #include "gmp-impl.h"
41 /**************************************************************/
42 /* Section macros: common macros, for mswing/fac/bin (&sieve) */
43 /**************************************************************/
45 #define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve) \
46 __max_i = (end); \
48 do { \
49 ++__i; \
50 if (((sieve)[__index] & __mask) == 0) \
51 { \
52 (prime) = id_to_n(__i)
54 #define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \
55 do { \
56 mp_limb_t __mask, __index, __max_i, __i; \
58 __i = (start)-(off); \
59 __index = __i / GMP_LIMB_BITS; \
60 __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \
61 __i += (off); \
63 LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
65 #define LOOP_ON_SIEVE_STOP \
66 } \
67 __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \
68 __index += __mask & 1; \
69 } while (__i <= __max_i) \
71 #define LOOP_ON_SIEVE_END \
72 LOOP_ON_SIEVE_STOP; \
73 } while (0)
75 /*********************************************************/
76 /* Section sieve: sieving functions and tools for primes */
77 /*********************************************************/
79 #if 0
80 static mp_limb_t
81 bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
82 #endif
84 /* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
85 static mp_limb_t
86 id_to_n (mp_limb_t id) { return id*3+1+(id&1); }
88 /* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
89 static mp_limb_t
90 n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
92 #if 0
93 static mp_size_t
94 primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
95 #endif
97 #if GMP_LIMB_BITS > 61
98 #define SIEVE_SEED CNST_LIMB(0x3294C9E069128480)
99 #define SEED_LIMIT 202
100 #else
101 #if GMP_LIMB_BITS > 30
102 #define SIEVE_SEED CNST_LIMB(0x69128480)
103 #define SEED_LIMIT 114
104 #else
105 #if GMP_LIMB_BITS > 15
106 #define SIEVE_SEED CNST_LIMB(0x8480)
107 #define SEED_LIMIT 54
108 #else
109 #if GMP_LIMB_BITS > 7
110 #define SIEVE_SEED CNST_LIMB(0x80)
111 #define SEED_LIMIT 34
112 #else
113 #define SIEVE_SEED CNST_LIMB(0x0)
114 #define SEED_LIMIT 24
115 #endif /* 7 */
116 #endif /* 15 */
117 #endif /* 30 */
118 #endif /* 61 */
120 static void
121 first_block_primesieve (mp_ptr bit_array, mp_limb_t n)
123 mp_size_t bits, limbs;
125 ASSERT (n > 4);
127 bits = n_to_bit(n);
128 limbs = bits / GMP_LIMB_BITS + 1;
130 /* FIXME: We can skip 5 too, filling with a 5-part pattern. */
131 MPN_ZERO (bit_array, limbs);
132 bit_array[0] = SIEVE_SEED;
134 if ((bits + 1) % GMP_LIMB_BITS != 0)
135 bit_array[limbs-1] |= MP_LIMB_T_MAX << ((bits + 1) % GMP_LIMB_BITS);
137 if (n > SEED_LIMIT) {
138 mp_limb_t mask, index, i;
140 ASSERT (n > 49);
142 mask = 1;
143 index = 0;
144 i = 1;
145 do {
146 if ((bit_array[index] & mask) == 0)
148 mp_size_t step, lindex;
149 mp_limb_t lmask;
150 unsigned maskrot;
152 step = id_to_n(i);
153 /* lindex = n_to_bit(id_to_n(i)*id_to_n(i)); */
154 lindex = i*(step+1)-1+(-(i&1)&(i+1));
155 /* lindex = i*(step+1+(i&1))-1+(i&1); */
156 if (lindex > bits)
157 break;
159 step <<= 1;
160 maskrot = step % GMP_LIMB_BITS;
162 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
163 do {
164 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
165 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
166 lindex += step;
167 } while (lindex <= bits);
169 /* lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); */
170 lindex = i*(i*3+6)+(i&1);
172 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
173 for ( ; lindex <= bits; lindex += step) {
174 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
175 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
178 mask = mask << 1 | mask >> (GMP_LIMB_BITS-1);
179 index += mask & 1;
180 i++;
181 } while (1);
185 static void
186 block_resieve (mp_ptr bit_array, mp_size_t limbs, mp_limb_t offset,
187 mp_srcptr sieve, mp_limb_t sieve_bits)
189 mp_size_t bits, step;
191 ASSERT (limbs > 0);
193 bits = limbs * GMP_LIMB_BITS - 1;
195 /* FIXME: We can skip 5 too, filling with a 5-part pattern. */
196 MPN_ZERO (bit_array, limbs);
198 LOOP_ON_SIEVE_BEGIN(step,0,sieve_bits,0,sieve);
200 mp_size_t lindex;
201 mp_limb_t lmask;
202 unsigned maskrot;
204 /* lindex = n_to_bit(id_to_n(i)*id_to_n(i)); */
205 lindex = __i*(step+1)-1+(-(__i&1)&(__i+1));
206 /* lindex = __i*(step+1+(__i&1))-1+(__i&1); */
207 if (lindex > bits + offset)
208 break;
210 step <<= 1;
211 maskrot = step % GMP_LIMB_BITS;
213 if (lindex < offset)
214 lindex += step * ((offset - lindex - 1) / step + 1);
216 lindex -= offset;
218 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
219 for ( ; lindex <= bits; lindex += step) {
220 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
221 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
224 /* lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); */
225 lindex = __i*(__i*3+6)+(__i&1);
226 if (lindex > bits + offset)
227 continue;
229 if (lindex < offset)
230 lindex += step * ((offset - lindex - 1) / step + 1);
232 lindex -= offset;
234 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
235 for ( ; lindex <= bits; lindex += step) {
236 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
237 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
240 LOOP_ON_SIEVE_END;
243 #define BLOCK_SIZE 2048
245 /* Fills bit_array with the characteristic function of composite
246 numbers up to the parameter n. I.e. a bit set to "1" represent a
247 composite, a "0" represent a prime.
249 The primesieve_size(n) limbs pointed to by bit_array are
250 overwritten. The returned value counts prime integers in the
251 interval [4, n]. Note that n > 4.
253 Even numbers and multiples of 3 are excluded "a priori", only
254 numbers equivalent to +/- 1 mod 6 have their bit in the array.
256 Once sieved, if the bit b is ZERO it represent a prime, the
257 represented prime is bit_to_n(b), if the LSbit is bit 0, or
258 id_to_n(b), if you call "1" the first bit.
261 mp_limb_t
262 gmp_primesieve (mp_ptr bit_array, mp_limb_t n)
264 mp_size_t size;
265 mp_limb_t bits;
267 ASSERT (n > 4);
269 bits = n_to_bit(n);
270 size = bits / GMP_LIMB_BITS + 1;
272 if (size > BLOCK_SIZE * 2) {
273 mp_size_t off;
274 off = BLOCK_SIZE + (size % BLOCK_SIZE);
275 first_block_primesieve (bit_array, id_to_n (off * GMP_LIMB_BITS));
276 for ( ; off < size; off += BLOCK_SIZE)
277 block_resieve (bit_array + off, BLOCK_SIZE, off * GMP_LIMB_BITS, bit_array, off * GMP_LIMB_BITS - 1);
278 } else {
279 first_block_primesieve (bit_array, n);
282 if ((bits + 1) % GMP_LIMB_BITS != 0)
283 bit_array[size-1] |= MP_LIMB_T_MAX << ((bits + 1) % GMP_LIMB_BITS);
286 return size * GMP_LIMB_BITS - mpn_popcount (bit_array, size);
289 #undef BLOCK_SIZE
290 #undef SEED_LIMIT
291 #undef SIEVE_SEED
292 #undef LOOP_ON_SIEVE_END
293 #undef LOOP_ON_SIEVE_STOP
294 #undef LOOP_ON_SIEVE_BEGIN
295 #undef LOOP_ON_SIEVE_CONTINUE