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, 2011, 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 the GNU Lesser General Public License as published by
16 the Free Software Foundation; either version 3 of the License, or (at your
17 option) any later version.
19 The GNU MP Library is distributed in the hope that it will be useful, but
20 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
21 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
22 License for more details.
24 You should have received a copy of the GNU Lesser General Public License
25 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
30 /**************************************************************/
31 /* Section macros: common macros, for mswing/fac/bin (&sieve) */
32 /**************************************************************/
34 #define LOOP_ON_SIEVE_CONTINUE(prime,end,sieve) \
39 if (((sieve)[__index] & __mask) == 0) \
41 (prime) = id_to_n(__i)
43 #define LOOP_ON_SIEVE_BEGIN(prime,start,end,off,sieve) \
45 mp_limb_t __mask, __index, __max_i, __i; \
47 __i = (start)-(off); \
48 __index = __i / GMP_LIMB_BITS; \
49 __mask = CNST_LIMB(1) << (__i % GMP_LIMB_BITS); \
52 LOOP_ON_SIEVE_CONTINUE(prime,end,sieve)
54 #define LOOP_ON_SIEVE_STOP \
56 __mask = __mask << 1 | __mask >> (GMP_LIMB_BITS-1); \
57 __index += __mask & 1; \
58 } while (__i <= __max_i) \
60 #define LOOP_ON_SIEVE_END \
64 /*********************************************************/
65 /* Section sieve: sieving functions and tools for primes */
66 /*********************************************************/
70 bit_to_n (mp_limb_t bit) { return (bit*3+4)|1; }
73 /* id_to_n (x) = bit_to_n (x-1) = (id*3+1)|1*/
75 id_to_n (mp_limb_t id) { return id*3+1+(id&1); }
77 /* n_to_bit (n) = ((n-1)&(-CNST_LIMB(2)))/3U-1 */
79 n_to_bit (mp_limb_t n) { return ((n-5)|1)/3U; }
83 primesieve_size (mp_limb_t n) { return n_to_bit(n) / GMP_LIMB_BITS + 1; }
86 #if GMP_LIMB_BITS > 61
87 #define SIEVE_SEED CNST_LIMB(0x3294C9E069128480)
88 #define SEED_LIMIT 202
90 #if GMP_LIMB_BITS > 30
91 #define SIEVE_SEED CNST_LIMB(0x69128480)
92 #define SEED_LIMIT 114
94 #if GMP_LIMB_BITS > 15
95 #define SIEVE_SEED CNST_LIMB(0x8480)
99 #define SIEVE_SEED CNST_LIMB(0x80)
100 #define SEED_LIMIT 34
102 #define SIEVE_SEED CNST_LIMB(0x0)
103 #define SEED_LIMIT 24
110 first_block_primesieve (mp_ptr bit_array, mp_limb_t n)
112 mp_size_t bits, limbs;
117 limbs = bits / GMP_LIMB_BITS + 1;
119 /* FIXME: We can skip 5 too, filling with a 5-part pattern. */
120 MPN_ZERO (bit_array, limbs);
121 bit_array[0] = SIEVE_SEED;
123 if ((bits + 1) % GMP_LIMB_BITS != 0)
124 bit_array[limbs-1] |= MP_LIMB_T_MAX << ((bits + 1) % GMP_LIMB_BITS);
126 if (n > SEED_LIMIT) {
127 mp_limb_t mask, index, i;
135 if ((bit_array[index] & mask) == 0)
137 mp_size_t step, lindex;
142 /* lindex = n_to_bit(id_to_n(i)*id_to_n(i)); */
143 lindex = i*(step+1)-1+(-(i&1)&(i+1));
144 /* lindex = i*(step+1+(i&1))-1+(i&1); */
149 maskrot = step % GMP_LIMB_BITS;
151 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
153 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
154 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
156 } while (lindex <= bits);
158 /* lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); */
159 lindex = i*(i*3+6)+(i&1);
161 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
162 for ( ; lindex <= bits; lindex += step) {
163 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
164 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
167 mask = mask << 1 | mask >> (GMP_LIMB_BITS-1);
175 block_resieve (mp_ptr bit_array, mp_size_t limbs, mp_limb_t offset,
176 mp_srcptr sieve, mp_limb_t sieve_bits)
178 mp_size_t bits, step;
182 bits = limbs * GMP_LIMB_BITS - 1;
184 /* FIXME: We can skip 5 too, filling with a 5-part pattern. */
185 MPN_ZERO (bit_array, limbs);
187 LOOP_ON_SIEVE_BEGIN(step,0,sieve_bits,0,sieve);
193 /* lindex = n_to_bit(id_to_n(i)*id_to_n(i)); */
194 lindex = __i*(step+1)-1+(-(__i&1)&(__i+1));
195 /* lindex = __i*(step+1+(__i&1))-1+(__i&1); */
196 if (lindex > bits + offset)
200 maskrot = step % GMP_LIMB_BITS;
203 lindex += step * ((offset - lindex - 1) / step + 1);
207 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
208 for ( ; lindex <= bits; lindex += step) {
209 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
210 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
213 /* lindex = n_to_bit(id_to_n(i)*bit_to_n(i)); */
214 lindex = __i*(__i*3+6)+(__i&1);
215 if (lindex > bits + offset)
219 lindex += step * ((offset - lindex - 1) / step + 1);
223 lmask = CNST_LIMB(1) << (lindex % GMP_LIMB_BITS);
224 for ( ; lindex <= bits; lindex += step) {
225 bit_array[lindex / GMP_LIMB_BITS] |= lmask;
226 lmask = lmask << maskrot | lmask >> (GMP_LIMB_BITS - maskrot);
232 #define BLOCK_SIZE 2048
234 /* Fills bit_array with the characteristic function of composite
235 numbers up to the parameter n. I.e. a bit set to "1" represent a
236 composite, a "0" represent a prime.
238 The primesieve_size(n) limbs pointed to by bit_array are
239 overwritten. The returned value counts prime integers in the
240 interval [4, n]. Note that n > 4.
242 Even numbers and multiples of 3 are excluded "a priori", only
243 numbers equivalent to +/- 1 mod 6 have their bit in the array.
245 Once sieved, if the bit b is ZERO it represent a prime, the
246 represented prime is bit_to_n(b), if the LSbit is bit 0, or
247 id_to_n(b), if you call "1" the first bit.
251 gmp_primesieve (mp_ptr bit_array, mp_limb_t n)
259 size = bits / GMP_LIMB_BITS + 1;
261 if (size > BLOCK_SIZE * 2) {
263 off = BLOCK_SIZE + (size % BLOCK_SIZE);
264 first_block_primesieve (bit_array, id_to_n (off * GMP_LIMB_BITS));
265 for ( ; off < size; off += BLOCK_SIZE)
266 block_resieve (bit_array + off, BLOCK_SIZE, off * GMP_LIMB_BITS, bit_array, off * GMP_LIMB_BITS - 1);
268 first_block_primesieve (bit_array, n);
271 if ((bits + 1) % GMP_LIMB_BITS != 0)
272 bit_array[size-1] |= MP_LIMB_T_MAX << ((bits + 1) % GMP_LIMB_BITS);
275 return size * GMP_LIMB_BITS - mpn_popcount (bit_array, size);
281 #undef LOOP_ON_SIEVE_END
282 #undef LOOP_ON_SIEVE_STOP
283 #undef LOOP_ON_SIEVE_BEGIN
284 #undef LOOP_ON_SIEVE_CONTINUE