File Coverage

almost_primes.c
Criterion Covered Total %
statement 358 447 80.0
branch 345 618 55.8
condition n/a
subroutine n/a
pod n/a
total 703 1065 66.0


line stmt bran cond sub pod time code
1             /******************************************************************************/
2             /* ALMOST PRIMES */
3             /******************************************************************************/
4              
5             #include
6             #include
7             #include
8             #include
9             #include "ptypes.h"
10             #include "constants.h"
11             #define FUNC_isqrt 1
12             #define FUNC_ctz 1
13             #include "sort.h"
14             #include "cache.h"
15             #include "sieve.h"
16             #include "util.h"
17             #include "prime_counts.h"
18             #include "prime_count_cache.h"
19             #include "semi_primes.h"
20             #include "inverse_interpolate.h"
21             #include "almost_primes.h"
22              
23             /******************************************************************************/
24             /* KAP UTILITY */
25             /******************************************************************************/
26              
27             #if BITS_PER_WORD == 32
28             static uint32_t const _pow3[21] = {1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,4782969,14348907,43046721,129140163,387420489,1162261467,3486784401U};
29             #else
30             static UV const _pow3[41] = {1,3,9,27,81,243,729,2187,6561,19683,59049,177147,531441,1594323,4782969,14348907,43046721,129140163,387420489,1162261467,3486784401U,UVCONST(10460353203),UVCONST(31381059609),UVCONST(94143178827),UVCONST(282429536481),UVCONST(847288609443),UVCONST(2541865828329),UVCONST(7625597484987),UVCONST(22876792454961),UVCONST(68630377364883),UVCONST(205891132094649),UVCONST(617673396283947),UVCONST(1853020188851841),UVCONST(5559060566555523),UVCONST(16677181699666569),UVCONST(50031545098999707),UVCONST(150094635296999121),UVCONST(450283905890997363),UVCONST(1350851717672992089),UVCONST(4052555153018976267),UVCONST(12157665459056928801)};
31             #endif
32             #define A078843_MAX_K 49
33             static const uint32_t _first_3[A078843_MAX_K+1] = {1, 2, 3, 5, 8, 14, 23, 39, 64, 103, 169, 269, 427, 676, 1065, 1669, 2628, 4104, 6414, 10023, 15608, 24281, 37733, 58503, 90616, 140187, 216625, 334527, 516126, 795632, 1225641, 1886570, 2901796, 4460359, 6851532, 10518476, 16138642, 24748319, 37932129, 58110457, 88981343, 136192537, 208364721, 318653143, 487128905, 744398307, 1137129971, 1736461477, 2650785552U, 4045250962U};
34              
35             /* For all n <= hi, we can get the same results using 2*result with lower k */
36 3           static uint32_t reduce_k_for_n(uint32_t k, UV n) {
37 3           uint32_t r = 0;
38 3 50         if (k <= 1 || k >= BITS_PER_WORD) return 0;
    50          
39 3 50         if (k > MPU_MAX_POW3) /* Larger n would not fit in a UV type */
40 0           r = k-MPU_MAX_POW3;
41 3 50         while ((k-r) > 1 && (n>>r) < _pow3[k-r])
    50          
42 0           r++;
43 3           return r;
44             }
45              
46             /* Least r s.t. almost_prime_count(k, n) = almost_prime_count(k-r, n >> r) */
47 555           static void reduce_prime_count_factor(uint32_t *pk, UV *n) {
48 555           uint32_t k = *pk, r = 0;
49 555 50         if (k > MPU_MAX_POW3) /* Larger n would not fit in a UV type */
50 0           r = k-MPU_MAX_POW3;
51 1903 50         while (k >= r && ((*n)>>r) < _pow3[k-r])
    100          
52 1348           r++;
53             /* Reduce */
54 555 100         if (r > 0) {
55 84           *pk -= r;
56 84           *n >>= r;
57             }
58 555           }
59              
60             /* Least r s.t. nth_almost_prime(k,n) = nth_almost_prime(k-r,n) << r */
61 24           static uint32_t reduce_nth_factor(uint32_t k, UV n) {
62 24           uint32_t r = 0;
63 24 50         if (k <= 1 || k >= BITS_PER_WORD) return 0;
    50          
64 24 50         if (k > A078843_MAX_K) {
65 0 0         if (n >= _first_3[A078843_MAX_K])
66 0           return 0;
67 0           r = k-A078843_MAX_K+1;
68             }
69 115 100         while (n < _first_3[k-r])
70 91           r++;
71 24           return r;
72             }
73              
74              
75             /* This could be easily extended to 16 or 32 */
76 2           static UV _fast_small_nth_almost_prime(uint32_t k, UV n) {
77             static const uint8_t semi[8] = {0, 4, 6, 9, 10, 14, 15, 21};
78             static const uint8_t mult[8] = {0, 8, 12, 18, 20, 27, 28, 30};
79 2 50         MPUassert(n < 8 && k >= 2, "Fast small nth almost prime out of range");
    50          
80 2 50         if (k == 2) return semi[n];
81 2           return mult[n] * (UVCONST(1) << (k-3));
82             }
83              
84             static void _almost_prime_count_bounds(UV *lower, UV *upper, uint32_t k, UV n);
85              
86             #if 0 /* Not currently used */
87             /* Somewhere around k=20 it is faster to do:
88             * return nth_almost_prime(h, 1+almost_prime_count(k,n));
89             */
90             static UV _next_almost_prime(uint32_t k, UV n) {
91             while (!is_almost_prime(k, ++n))
92             ;
93             return n;
94             }
95             static UV _prev_almost_semiprime(uint32_t k, UV n) {
96             while (!is_almost_prime(k, --n))
97             ;
98             return n;
99             }
100             #endif
101              
102              
103             /******************************************************************************/
104             /* KAP COUNT */
105             /******************************************************************************/
106              
107             #define CACHED_PC(cache,n) prime_count_cache_lookup(cache,n)
108              
109             /* Debatably useful. Slightly faster for small n, the same for larger. */
110 4           static UV almost3prime_count(UV n) {
111 4           UV sum = 0, cbrtn = prev_prime(rootint(n,3)+1);
112 4           void *cache = prime_count_cache_create( (UV)pow(n,0.72) );
113              
114 43 50         SIMPLE_FOR_EACH_PRIME(2, cbrtn) {
    100          
    50          
115 35           UV pdiv = p, lo = p, hi = isqrt(n/pdiv);
116 35           UV j = CACHED_PC(cache, lo) - 1; /* IDX(Pi) */
117 35 100         if ((lo <= 2) && (hi >= 2)) sum += CACHED_PC(cache,n/(pdiv*2)) - j++;
    50          
118 35 100         if ((lo <= 3) && (hi >= 3)) sum += CACHED_PC(cache,n/(pdiv*3)) - j++;
    50          
119 35 100         if ((lo <= 5) && (hi >= 5)) sum += CACHED_PC(cache,n/(pdiv*5)) - j++;
    100          
120 35 100         if (lo < 7) lo = 7;
121 35 100         if (lo <= hi) {
122             unsigned char* segment;
123             UV seg_base, seg_low, seg_high;
124 32           void* ctx = start_segment_primes(lo, hi, &segment);
125 64 100         while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
126 1040 50         START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high )
    100          
    100          
    100          
    100          
127 903           sum += CACHED_PC(cache,n/(pdiv*p)) - j++;
128 41           END_DO_FOR_EACH_SIEVE_PRIME
129             }
130 32           end_segment_primes(ctx);
131             }
132             } END_SIMPLE_FOR_EACH_PRIME
133 4           prime_count_cache_destroy(cache);
134 4           return sum;
135             }
136              
137             /* almost_prime_count(k,n) is the main interface, it will call the recursive
138             * function _cs(), with the terminal function _final_sum(). */
139              
140             /* for Pi from Pi to isqrt(N/Pi) [pc[n/Pi]-idx(Pi)+1] */
141             /* semiprime count = _final_sum(n, 1, 2, cache); */
142             /* 3-almost prime count = sum(Pj < icbrt(n) of _final_sum(n, Pj, Pj, cache); */
143 3081           static UV _final_sum(UV n, UV pdiv, UV lo, void *cache) {
144 3081           UV s = 0, hi = isqrt(n/pdiv);
145 3081           UV j = CACHED_PC(cache, lo) - 1; /* IDX(Pi) */
146              
147 3081 50         if (hi-lo < 500) {
148 26472 50         SIMPLE_FOR_EACH_PRIME(lo, hi) {
    100          
    50          
149 20310           s += CACHED_PC(cache,n/(pdiv*p)) - j++;
150             } END_SIMPLE_FOR_EACH_PRIME
151 3081           return s;
152             }
153              
154 0 0         if ((lo <= 2) && (hi >= 2)) s += CACHED_PC(cache,n/(pdiv*2)) - j++;
    0          
155 0 0         if ((lo <= 3) && (hi >= 3)) s += CACHED_PC(cache,n/(pdiv*3)) - j++;
    0          
156 0 0         if ((lo <= 5) && (hi >= 5)) s += CACHED_PC(cache,n/(pdiv*5)) - j++;
    0          
157 0 0         if (lo < 7) lo = 7;
158 0 0         if (lo <= hi) {
159             unsigned char* segment;
160             UV seg_base, seg_low, seg_high;
161 0           void* ctx = start_segment_primes(lo, hi, &segment);
162 0 0         while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
163 0 0         START_DO_FOR_EACH_SIEVE_PRIME( segment, seg_base, seg_low, seg_high )
    0          
    0          
    0          
    0          
164 0           s += CACHED_PC(cache,n/(pdiv*p)) - j++;
165 0           END_DO_FOR_EACH_SIEVE_PRIME
166             }
167 0           end_segment_primes(ctx);
168             }
169 0           return s;
170             }
171              
172 2286           static UV _cs(UV n, UV pdiv, UV lo, uint32_t k, void *cache) {
173 2286           UV count = 0;
174              
175 2286 50         if (k == 2)
176 0           return _final_sum(n, pdiv, lo, cache);
177              
178 9909 50         SIMPLE_FOR_EACH_PRIME(lo, rootint(n/pdiv,k)) {
    100          
    50          
179 5337 100         if (k == 3) count += _final_sum(n, pdiv*p, p, cache);
180 2256           else count += _cs(n, pdiv*p, p, k-1, cache);
181             } END_SIMPLE_FOR_EACH_PRIME
182              
183 2286           return count;
184             }
185              
186 47           UV almost_prime_count(uint32_t k, UV n)
187             {
188             void* cache;
189             UV count, csize;
190              
191 47 100         if (k == 0) return (n >= 1);
192 46 50         if (k >= BITS_PER_WORD || (n >> k) == 0) return 0;
    100          
193 42           reduce_prime_count_factor(&k, &n); /* Reduce to lower k,n if possible */
194              
195 42 100         if (n >= max_nth_almost_prime(k))
196 1           return max_almost_prime_count(k);
197              
198 41 50         if (k == 0) return n;
199 41 100         if (k == 1) return prime_count(n);
200 37 100         if (k == 2) return semiprime_count(n);
201 34 100         if (k == 3) return almost3prime_count(n);
202 30 50         if (n < 3*(UVCONST(1) << (k-1))) return 1;
203 30 50         if (n < 9*(UVCONST(1) << (k-2))) return 2;
204 30 50         if (n < 10*(UVCONST(1) << (k-2))) return 3;
205              
206             /* Decide how much we will cache prime counts.
207             *
208             * n/(1UL << (k+M)) has 0,1,2,7,15,37,84,187,... lookups for M=-2,-1,0,...
209             * The number of non-cached counts performed follows OEIS A052130. */
210              
211 30           csize = n / (1UL << (k-2));
212 30 100         if (csize < 32) csize = 32;
213 30 100         if (csize > 16UL*1024) csize = n / (1UL << (k+2)); /* 15 */
214 30 50         if (csize > 128UL*1024) csize = n / (1UL << (k+4)); /* 84 */
215 30 50         if (csize > 1UL*1024*1024) csize = n / (1UL << (k+6)); /* 421 */
216 30 50         if (((csize >> 16) >> 16) >= 3) csize >>= 1;
217              
218 30           cache = prime_count_cache_create( csize );
219 30           count = _cs(n, 1, 2, k, cache);
220 30           prime_count_cache_destroy(cache);
221 30           return count;
222             }
223              
224 0           UV almost_prime_count_range(uint32_t k, UV lo, UV hi) {
225 0 0         if (k == 0) return (lo <= 1 && hi >= 1);
    0          
    0          
226 0 0         if (k == 1) return prime_count_range(lo, hi);
227 0 0         if (k == 2) return semiprime_count_range(lo, hi);
228             /* See semiprime_count. Possibly clever solutions for small ranges. */
229 0 0         if (k >= BITS_PER_WORD || (hi >> k) == 0 || hi < lo) return 0;
    0          
    0          
230 0           return almost_prime_count(k, hi)
231 0 0         - (((lo >> k) == 0) ? 0 : almost_prime_count(k,lo-1));
232             }
233              
234 159           UV almost_prime_count_approx(uint32_t k, UV n) {
235             UV lo, hi;
236              
237 159 50         if (k == 0) return (n >= 1);
238 159 50         if (k >= BITS_PER_WORD || (n >> k) == 0) return 0;
    100          
239 150           reduce_prime_count_factor(&k, &n); /* Reduce to lower k,n if possible */
240              
241 150 100         if (k == 1) return prime_count_approx(n);
242 149 100         if (k == 2) return semiprime_count_approx(n);
243 148 50         if (n < 3*(UVCONST(1) << (k-1))) return 1;
244 148 50         if (n < 9*(UVCONST(1) << (k-2))) return 2;
245 148 50         if (n < 10*(UVCONST(1) << (k-2))) return 3;
246              
247 148 100         if (k == 3 && n < 102) {
    100          
248 3           unsigned char const sm3[19] = {27,28,30,42,44,45,50,52,63,66,68,70,75,76,78,92,98,99};
249 12 50         for (lo=0; lo < 19; lo++)
250 12 100         if (n < sm3[lo])
251 3           break;
252 3           return 4+lo;
253             }
254              
255 145           _almost_prime_count_bounds(&lo, &hi, k, n);
256              
257 145 100         if (k == 3) { /* Much better fit for k=3. */
258 37           double x = n, logx = log(x), loglogx = log(logx);
259 37           double a = 1.0, s = 2.0;
260             UV est;
261 37 100         if (x <= 638) { s = 1.554688; a = 0.865814; }
262 25 100         else if (x <= 1544) { s = 1.050000; a = 0.822256; }
263 23 100         else if (x <= 1927) { s = 0.625000; a = 0.791747; }
264 15 100         else if (x <= 486586) { s = 2.865611; a = 1.004090; }
265 4 50         else if (x <= 1913680) { s = 2.790963; a = 0.999618; }
266 4 50         else if (x <= 22347532) { s = 2.719238; a = 0.995635; }
267 4 100         else if (x <= 2.95e8) { s = 2.584473; a = 0.988802; }
268 2 50         else if (x <= 4.20e9) { s = 2.457108; a = 0.983098; }
269 2 50         else if (x <= 7.07e10) { s = 2.352818; a = 0.978931; }
270 2 50         else if (x <= 1.36e12) { s = 2.269745; a = 0.975953; }
271 2 50         else if (x <= 4.1e13) { s = 2.203002; a = 0.973796; }
272 0 0         else if (x <= 9.2e14) { s = 2.148463; a = 0.972213; }
273 0           else { s = 2.119279; a = 0.971438; }
274 37           est = 0.5 * a * x * ((loglogx+0.26153)*(loglogx+0.26153)) / (logx+s)+0.5;
275 37 50         if (est < lo) est = lo;
276 37 50         else if (est > hi) est = hi;
277 37           return est;
278             }
279              
280             #if 0 /* Equation 6 from https://arxiv.org/pdf/2103.09866v3.pdf */
281             {
282             const double nu[21] = {
283             1.0, 2.61497e-1, -5.62153e-1, 3.05978e-1, 2.62973e-2, -6.44501e-2,
284             3.64064e-2, -4.70865e-3, -4.33984e-4, 1.50850e-3, -1.83548e-4,
285             1.49365e-4, 4.99174e-5, 1.82657e-5, 1.30241e-5, 5.52779e-6,
286             2.90194e-6, 1.45075e-6, 7.19861e-7, 3.61606e-7, 1.80517e-7 };
287             double sum = 0, x = n, logx = log(x), loglogx = log(logx);
288             uint32_t i, j;
289             for (j = 0; j < k; j++) {
290             uint32_t idx = k-1-j;
291             double v = (idx <= 20) ? nu[idx] : 0.1893475 * powl(2.0, -(double)k);
292             for (i = 1; i <= j; i++)
293             v = v * loglogx / i;
294             sum += v;
295             }
296             sum = (x / logx) * sum;
297             return (UV) (sum+0.5);
298             }
299             #endif
300              
301             /* We should look at (1) better bounds, (2) better weighting here */
302             /* return lo + (hi-lo)/2; */
303             /* Consider two variables to control our weight: k and n */
304 108 100         if (k > 11) return lo + (hi-lo) * 0.20;
305 67           return lo + (hi-lo) * 0.76;
306             }
307              
308              
309             /******************************************************************************/
310             /* NTH KAP */
311             /******************************************************************************/
312              
313             #if 0
314             /* Asymptotic estimate for the nth k-almost prime */
315             static double _asymptotic_nth(uint32_t k, UV n) {
316             uint32_t i; double x, logn, loglogn;
317             if (k == 0 || n == 0) return 0;
318             if (n == 1) return UVCONST(1) << k;
319             logn = log(n);
320             loglogn = log(logn);
321             x = n * logn;
322             for (i = 1; i < k; i++)
323             x *= (double)i / loglogn;
324             return x;
325             }
326             #endif
327              
328 161           static UV apcu(UV mid, UV k) { return almost_prime_count_upper(k, mid); }
329 53           static UV apcl(UV mid, UV k) { return almost_prime_count_lower(k, mid); }
330 123           static UV apca(UV mid, UV k) { return almost_prime_count_approx(k, mid); }
331 12           static UV apce(UV mid, UV k) { return almost_prime_count(k, mid); }
332              
333 5           UV nth_almost_prime_upper(uint32_t k, UV n) {
334             UV r, maxc, maxn, lo, up;
335              
336 5 50         if (n == 0) return 0;
337 5 50         if (k == 0) return (n == 1) ? 1 : 0;
338 5 50         if (k == 1) return nth_prime_upper(n);
339 5 50         if (n < 8) return _fast_small_nth_almost_prime(k, n);
340              
341 5           maxn = max_nth_almost_prime(k);
342 5           maxc = max_almost_prime_count(k);
343 5 50         if (n >= maxc) return n == maxc ? maxn : 0;
    0          
344              
345 5           r = reduce_nth_factor(k,n);
346 5 100         if (r > 0) {
347 1           UV redup = nth_almost_prime_upper(k-r, n);
348 1 50         if (redup > maxn || ((redup<>r) != redup)
    50          
349 0           return maxn;
350 1           return redup << r;
351             }
352              
353             /* We start out with the literal min and max because we have NO idea. */
354 4           lo = UVCONST(5) << k; /* For k >= 1 and n >= 8 */
355              
356 4           up = inverse_interpolate_k(lo, 0, n, k, &apcl, 0);
357 4           return up > maxn ? maxn : up;
358             }
359              
360 14           UV nth_almost_prime_lower(uint32_t k, UV n) {
361             UV r, maxc, lo;
362              
363 14 50         if (n == 0) return 0;
364 14 50         if (k == 0) return (n == 1) ? 1 : 0;
365 14 50         if (k == 1) return nth_prime_lower(n);
366 14 50         if (n < 8) return _fast_small_nth_almost_prime(k, n);
367              
368 14           maxc = max_almost_prime_count(k);
369 14 50         if (n >= maxc) return n == maxc ? max_nth_almost_prime(k) : 0;
    0          
370              
371 14           r = reduce_nth_factor(k,n);
372 14 100         if (r > 0) return nth_almost_prime_lower(k-r, n) << r;
373              
374             /* We start out with the literal min and max because we have NO idea. */
375             /* \_/ note 3 instead of 5! TODO: apcu is not tight enough, so reduce */
376 12           lo = UVCONST(3) << k; /* For k >= 1 and n >= 8 */
377              
378 12           return inverse_interpolate_k(lo, 0, n, k, &apcu, 0);
379             }
380              
381 10           UV nth_almost_prime_approx(uint32_t k, UV n) {
382             UV maxc, lo;
383              
384 10 50         if (n == 0) return 0;
385 10 50         if (k == 0) return (n == 1) ? 1 : 0;
386 10 100         if (k == 1) return nth_prime_approx(n);
387 9 100         if (k == 2) return nth_semiprime_approx(n);
388              
389 8           maxc = max_almost_prime_count(k);
390 8 50         if (n >= maxc) return n == maxc ? max_nth_almost_prime(k) : 0;
    0          
391              
392             /* We could reduce but really no reason to do it */
393              
394 8 50         if (n < 8) return _fast_small_nth_almost_prime(k,n);
395 8           lo = nth_almost_prime_lower(k,n);
396              
397 8           return inverse_interpolate_k(lo, 0, n, k, &apca, 0);
398             }
399              
400 1           static UV _cb_nth3(UV n) { return nth_almost_prime_approx(3,n); }
401 1           static UV _cb_cnt3(UV n) { return almost_prime_count(3,n); }
402 4           static bool _cb_is3(UV n) { return is_almost_prime(3,n); }
403              
404 1           static UV _cb_nth4(UV n) { return nth_almost_prime_approx(4,n); }
405 1           static UV _cb_cnt4(UV n) { return almost_prime_count(4,n); }
406 221           static bool _cb_is4(UV n) { return is_almost_prime(4,n); }
407              
408 10           UV nth_almost_prime(uint32_t k, UV n) {
409             UV r, lo, hi, maxc;
410              
411 10 50         if (n == 0) return 0;
412 10 50         if (k == 0) return (n == 1) ? 1 : 0;
413 10 100         if (k == 1) return nth_prime(n);
414 9 100         if (k == 2) return nth_semiprime(n);
415              
416 7           maxc = max_almost_prime_count(k);
417 7 50         if (n >= maxc) return n == maxc ? max_nth_almost_prime(k) : 0;
    0          
418              
419             /* For k >= 3 and small n we can answer this quickly. */
420 7 100         if (n < 8) return _fast_small_nth_almost_prime(k,n);
421 5           r = reduce_nth_factor(k,n);
422 5 100         if (r > 0) return nth_almost_prime(k-r,n) << r;
423             /* NOTE: given n a 64-bit integer, k always <= 40 after reduction */
424              
425             /* Using the approximation to narrow in is *much* more efficient. But
426             * there is no good way to make it generic without closures (GCC extension)
427             * or statics (not thread-safe). */
428 4 100         if (k == 3)
429 1           return interpolate_with_approx(n, 0, 20000, &_cb_nth3, &_cb_cnt3, &_cb_is3);
430 3 100         if (k == 4)
431 1           return interpolate_with_approx(n, 0, 20000, &_cb_nth4, &_cb_cnt4, &_cb_is4);
432              
433 2           lo = nth_almost_prime_lower(k,n);
434 2           hi = nth_almost_prime_upper(k,n);
435 2           hi = inverse_interpolate_k(lo, hi, n, k, &apce, 60000);
436 6234 100         while (!is_almost_prime(k,hi))
437 6232           hi--;
438 2           return hi;
439             }
440              
441              
442             /******************************************************************************/
443             /* Bounds */
444             /******************************************************************************/
445              
446             /* Bayless et al. (2018) and Kinlaw (2019) are main references.
447             *
448             * https://www.researchgate.net/publication/329788487_Sums_over_primitive_sets_with_a_fixed_number_of_prime_factors
449             * http://math.colgate.edu/~integers/t22/t22.pdf
450             * https://arxiv.org/pdf/2103.09866v3.pdf
451             *
452             * Note that they use Pi_k(x) to mean square-free numbers, and
453             * Tau_k(x) to mean the general count like we use.
454             * They also have results for k = 2,3,4 only.
455             * Also see https://archimede.mat.ulaval.ca/MAINE-QUEBEC/19/Kinlaw19.pdf.
456             *
457             * We split into three ranges:
458             * 1 - 2^20 complete computations
459             * 2^20 - 2^32 complete computations
460             * 2^32 - 2^64 correct upper for k=2,3,4. correct lower for k=2.
461             * empirical for other k.
462             *
463             */
464              
465             static const double _upper_20[13] = {0,0, 1.006,0.7385,0.6830,0.5940,0.3596,0.2227,0.1439, 0.09785,0.07016,0.05303,0.04202};
466             static const double _upper_32[21] = {0,0, 1.013,0.8094,0.7485,
467             /* 5-12 */ 0.6467,0.3984,0.2464,0.1572,0.1049,0.07364,0.05452,0.04266,
468             /* 13-20 */ 0.03542,0.03082,0.02798,0.02642,0.02585,0.02615,0.02808,0.03054};
469             static const double _upper_64[41] = {0,0, 1.028, 1.028, 1.3043,/* <--corrrect */
470             /* 5-12 */
471             0.72208, 0.46609, 0.29340,0.18571,0.12063,0.0815,0.0575,0.0427,
472             /* 13-20 */
473             0.03490, 0.03007, 0.02710, 0.02554, 0.02504, 0.02554, 0.02699, 0.02954,
474             /* 21-28 */
475             0.03294, 0.03779, 0.04453, 0.05393, 0.06703, 0.08543, 0.1117, 0.1494,
476             /* 29-31 */
477             0.205,0.287,0.410,
478             /* 32-40 */
479             0.60,0.90,1.36,2.12,3.35,5.38,8.83,14.75,25.07,
480             };
481              
482             static const double _lower_20[13] = {0,0, 0.8197, 0.8418, 0.5242,
483             /* 5-12 */ 0.5154,0.3053,0.1901,0.1253,0.0892,0.06551,0.05082,0.04101};
484             static const double _lower_32[21] = {0,0, 1.004, 0.7383, 0.6828,
485             /* 5-12 */ 0.5939,0.3594,0.2222,0.1438,0.09754,0.06981,0.05245,0.04151,
486             /* 13-20 */ 0.03461,0.03006,0.02709,0.02553,0.02502,0.02552,0.02697,0.02945 };
487             static const double _lower_64[41] = {0,0, 1.011, 0.8093, 0.7484,
488             /* 5-12 */
489             0.6465,0.3982,0.2463,0.1571,0.1048,0.07363,0.0545,0.0422,
490             /* 13-20 */
491             0.0331,0.0270,0.0232,0.0208,0.0194,0.0190,0.0193,0.0203,
492             /* 21-28 */
493             0.0222,0.0252,0.0295,0.0356,0.0444,0.0570,0.0753,0.102,
494             /* 29-31 */
495             0.14,0.20,0.297,
496             /* 32-40 */
497             0.44,0.68,1.07,1.71,2.8,4.7,8.0,13.89,23.98,
498             };
499              
500             /*
501             k,count n <= 2^64-1
502             1,425656284035217743
503             2,1701748900850019777 10 hours
504             3,3167597434038354478 320 hours
505             4,3787884015050788482 322 hours
506             5,3378907169603895030 294 hours
507             6,2466706950238087748 209 hours
508             7,1571012171387856192 123 hours
509             8,913164427599983727 82 hours
510             9,499840874923678341 42 hours
511             10,263157990621533964 20 hours
512             11,135128109904869290 12 hours
513             12,68283616225825256 7 hours
514             13,34151861008771016 4 hours
515             14,16967424859951587 2 hours
516             15,8393048221327186
517             16,4139595949113890
518             17,2037655246635364
519             18,1001591348315641
520             19,491808604962296
521             20,241293656953012
522             21,118304122014405
523             22,57968649799947
524             23,28388662714236
525             24,13895161400556
526             25,6797526392535
527             26,3323560145881
528             27,1624109166018
529             28,793189260998
530             29,387148515886
531             30,188844769357
532             31,92054377509
533             32,44841620426
534             33,21827124353
535             34,10616326552
536             35,5159281045
537             36,2505087309
538             37,1215204383
539             38,588891145
540             39,285076316
541             40,137840686
542             */
543              
544 363           static void _almost_prime_count_bounds(UV *lower, UV *upper, uint32_t k, UV n) {
545             double x, logx, loglogx, logplus, multl, multu, boundl, boundu;
546             UV max;
547             uint32_t i;
548              
549 363 50         if (k >= BITS_PER_WORD || (n >> k) == 0) { *lower = *upper = 0; return; }
    50          
550 363           reduce_prime_count_factor(&k, &n); /* Reduce to lower k,n if possible */
551 363 50         if (k == 0) { *lower = *upper = (n >= 1); return; }
552 363 50         if (k == 1) { *lower = prime_count_lower(n); *upper = prime_count_upper(n); return; }
553 363 50         if (n < 3*(UVCONST(1) << (k-1))) { *lower = *upper = 1; return; }
554 363 50         if (n < 9*(UVCONST(1) << (k-2))) { *lower = *upper = 2; return; }
555 363 50         if (n < 10*(UVCONST(1) << (k-2))) { *lower = *upper = 3; return; }
556              
557 363           max = max_almost_prime_count(k);
558 363 50         if (n >= max_nth_almost_prime(k))
559 0           { *lower = *upper = max; return; }
560              
561 363           x = (double) n;
562 363           logx = log(x);
563 363           loglogx = log(logx);
564 363           logplus = loglogx + 0.26153;
565              
566             /* Select the appropriate table for n's range.
567             * 20/32/64-bit n will always reduce k to these limits. */
568 363 100         if (n <= 1048575U) {
569 234 50         MPUassert(k <= 12, "almost prime count: 20-bit n doesn't exceed k 12");
570 234           multu = _upper_20[k]; multl = _lower_20[k];
571 129 100         } else if (n <= 4294967295U) {
572 123 50         MPUassert(k <= 20, "almost prime count: 32-bit n doesn't exceed k 20");
573 123           multu = _upper_32[k]; multl = _lower_32[k];
574             } else {
575 6 50         MPUassert(k <= 40, "almost prime count: after reduction, k <= 40");
576 6           multu = _upper_64[k]; multl = _lower_64[k];
577             }
578              
579 363 100         if (k == 2) {
580 12           boundl = boundu = x * (loglogx + 0.261536) / logx;
581 12 50         if (x >= 1e12) {
582 0           boundl = x*(loglogx+0.1769)/logx * (1+0.4232/logx);
583 0           multl = 1;
584             }
585 351 100         } else if (k == 3) {
586 107           boundu = x * (logplus*logplus + 1.055852) / (2*logx);
587             /* Kinlaw (2019) Theorem 1 (with 1.000) */
588 107           boundl = x * loglogx * loglogx / (2*logx);
589 107 100         if (n < 638) {
590 37           multl = 0.8418;
591 70 100         } else if (n <= 1926) {
592 19           double weight = (x - 638L) / (double)(1926 - 638);
593 19           multl = (1L-weight) * 0.8939 + weight * 0.9233;
594 51 100         } else if (n <= 500194) {
595 47           double weight = (x - 1927L) / (double)(500194 - 1927);
596 47           multl = (1L-weight) * 0.9233 + weight * 1.000;
597 4 100         } else if (n <= 3184393786U) {
598 2           double weight = (x - 500194L) / (double)(3184393786U - 500194U);
599 2           multl = (1L-weight) * 1.0000 + weight * 1.039;
600             } else { /* TODO blend down to this */
601 2           multl = 1.0004;
602             }
603             /* Bayless (2018) Theorem 5.3 proves that multu=1.028 is a correct bound
604             * for all x >= 10^12. However it is not a tight bound for the range
605             * 2^32 to 2^64. We tighten it a lot for the reduced range.
606             */
607 107 100         if (n > 4294967295U) multu = 0.8711;
608 244 100         } else if (k == 4) {
609             /* Bayless doesn't discuss a lower bound for k=4. */
610             /* Bayless Theorem 5.4 part 1 (with multu = 1.3043) */
611 89           boundl = boundu = x * logplus*logplus*logplus / (6*logx);
612             /* Bayless Theorem 5.4 part 2 */
613 89 100         if (x > 1e12) {
614 2           boundu += 0.511977 * x * (log(log(x/4)) + 0.261536) / logx;
615 2           multu = 1.028;
616             }
617             /* As with k=3, adjust to tighten in the finite range. */
618 89 100         if (n > 4294967295U) multu = 0.780;
619 89 100         if (x > 1e12) multu = 0.6921;
620             } else {
621             /* Completely empirical and by no means optimal.
622             * It is easy and seems fairly reasonable through k=20 or so.
623             *
624             * For high k, this follows the lower bound well but upper grows too fast.
625             */
626 155           boundl = x / logx;
627 155           logplus = loglogx + (log(k)*log(log(k))-0.504377); /* k=5 => 0.26153 */
628 2134 100         for (i = 1; i < k; i++)
629 1979           boundl *= logplus / (double)i;
630 155           boundu = boundl;
631             }
632              
633             #if 0
634             printf(" lower: %lf * %lf = %lf\n", boundl, multl, boundl*multl);
635             printf(" upper: %lf * %lf = %lf\n", boundu, multu, boundu*multu);
636             printf(" max: %lu\n", max);
637             #endif
638 363           boundl *= multl;
639 363           boundu *= multu;
640              
641 363 50         *lower = (boundl >= UV_MAX || (max > 0 && boundl > max)) ? max : (UV)boundl;
    50          
    50          
642 363 50         *upper = (boundu >= UV_MAX || (max > 0 && boundu > max)) ? max : (UV)(boundu+1.0);
    50          
    50          
643             }
644              
645 163           UV almost_prime_count_upper(uint32_t k, UV n) {
646             UV l, u;
647 163 50         if (k == 2 && n < 256) return semiprime_count(n);
    0          
648 163           _almost_prime_count_bounds(&l, &u, k, n);
649 163           return u;
650             }
651              
652 55           UV almost_prime_count_lower(uint32_t k, UV n) {
653             UV l, u;
654 55 50         if (k == 2 && n < 256) return semiprime_count(n);
    0          
655 55           _almost_prime_count_bounds(&l, &u, k, n);
656 55           return l;
657             }
658              
659 448           UV max_nth_almost_prime(uint32_t k) {
660             #if BITS_PER_WORD == 32
661             static const UV offset[32] = {UV_MAX-1,4,1,9,5,0,7,47,31,3,15,511,1263,5119,1023,255,23295,2559,4095,126975,16383,262143,2359295,2097151,5767167,1048575,33554431,16777215,100663295,67108863,268435455,1073741823};
662             #else
663             static const UV offset[64] = {UV_MAX-1,58,14,2,4,
664             /* 5-12 */ 3,17,0,1,195,51,127,63,
665             /* 13-22 */ 767,1535,511,255,15,8191,1023,83967,16383,111615,
666             /* 23-32 */ 557055,2097151,524287,65535,1048575,6553599,33554431,4194303,671088639,16777215,
667             /* 33-63 */ UVCONST(536870911),UVCONST(2684354559),UVCONST(2147483647),
668             UVCONST(25769803775),UVCONST(4294967295),UVCONST(268435455),
669             UVCONST(206158430207),UVCONST(137438953471),UVCONST(17179869183),
670             UVCONST(68719476735),UVCONST(2199023255551),UVCONST(5428838662143),
671             UVCONST(21990232555519),UVCONST(4398046511103),UVCONST(1099511627775),
672             UVCONST(100055558127615),UVCONST(10995116277759),UVCONST(17592186044415),
673             UVCONST(545357767376895),UVCONST(70368744177663),UVCONST(1125899906842623),
674             UVCONST(10133099161583615),UVCONST(9007199254740991),
675             UVCONST(24769797950537727),UVCONST(4503599627370495),
676             UVCONST(144115188075855871),UVCONST(72057594037927935),
677             UVCONST(432345564227567615),UVCONST(288230376151711743),
678             UVCONST(1152921504606846975),UVCONST(4611686018427387903)
679             };
680             #endif
681 448 50         if (k >= BITS_PER_WORD) return 0;
682 448           return UV_MAX - offset[k];
683             }
684              
685 420           UV max_almost_prime_count(uint32_t k) {
686             #if BITS_PER_WORD == 32
687             static const UV max[32] = {1,203280221,658662065,967785236,916899721,665533848,410630859,229679168,121092503,61600699,30653019,15043269,7315315,3535071,1700690,814699,389357,185245,87964,41599,19611,9184,4283,2001,914,421,187,84,37,15,7,2};
688             #else
689             static const UV max[64] = {1,
690             UVCONST( 425656284035217743), /* max prime count */
691             UVCONST(1701748900850019777), /* max semiprime count */
692             UVCONST(3167597434038354478), /* max 3-almost-prime count */
693             UVCONST(3787884015050788482), /* max 4-almost-prime count */
694             /* 5-12 */ UVCONST(3378907169603895030),UVCONST(2466706950238087748),UVCONST(1571012171387856192),UVCONST(913164427599983727),UVCONST(499840874923678341),UVCONST(263157990621533964),UVCONST(135128109904869290),UVCONST(68283616225825256),
695             /* 13-22 */ UVCONST(34151861008771016),UVCONST(16967424859951587),UVCONST(8393048221327186),UVCONST(4139595949113890),UVCONST(2037655246635364),UVCONST(1001591348315641),UVCONST(491808604962296),UVCONST(241293656953012),UVCONST(118304122014405),UVCONST(57968649799947),
696             /* 23-32 */ UVCONST(28388662714236),UVCONST(13895161400556),UVCONST(6797526392535),UVCONST(3323560145881),UVCONST(1624109166018),UVCONST(793189260998),UVCONST(387148515886),UVCONST(188844769357),UVCONST(92054377509),UVCONST(44841620426),
697             /* 33-63 */ UVCONST(21827124353),UVCONST(10616326552),UVCONST(5159281045),UVCONST(2505087309),1215204383,588891145,285076316,137840686,66567488,32103728,15460810,7433670,3567978,1709640,817053,389954,185387,87993,41604,19611,9184,4283,2001,914,421,187,84,37,15,7,2
698             };
699             #endif
700 420 50         if (k >= BITS_PER_WORD) return 0;
701             /* if (max[k] == 0) return UV_MAX; All filled in so no need */
702 420           return max[k];
703             }
704              
705              
706             /******************************************************************************/
707             /* Construction */
708             /******************************************************************************/
709              
710             /* There are a few options for constructing KAPs without sieving/factoring.
711             *
712             * 1) we can make an iterator that recursively constructs them using
713             * a prime list and a k-1 iterator. This is a generalization of
714             * Dijkstra's Hamming number algorithm.
715             *
716             * 2) Given a range [lo,hi], We can ask for all k-1 kaps less than hi/2,
717             * then multiply through by primes to see which fall in our range.
718             *
719             * Each of these (and sieving) is limited in some ways. For example, #1
720             * can output 500-almost-primes quite rapidly which some other methods have
721             * trouble with, even with all the calculation in Perl. But it rapidly
722             * slows down with increasing n.
723             *
724             * I suspect there are far more efficient methods.
725             */
726              
727 0           static void _tidy_list(UV **list, UV *Lsize, UV *count, bool minimal) {
728 0           UV *L = *list;
729              
730 0 0         if (*count > 1) {
731             UV i, j;
732 0           sort_uv_array(L, *count);
733 0 0         for (j = 0, i = 1; i < *count; i++) {
734 0 0         if (L[i] != L[j])
735 0           L[++j] = L[i];
736             }
737 0           *count = j+1;
738             }
739 0 0         if (minimal) {
740 0           *Lsize = *count;
741 0 0         Renew(*list, *Lsize, UV);
742 0 0         } else if (*count * 1.5 > *Lsize) {
743 0           *Lsize = *count * 2 + 100;
744 0 0         Renew(*list, *Lsize, UV);
745             }
746 0           }
747              
748 0           UV range_construct_almost_prime(UV** list, uint32_t k, UV lo, UV hi) {
749 0           UV *L, minkap1, lastprime, count = 0;
750              
751 0 0         if (k == 0 || k >= BITS_PER_WORD) { *list = 0; return 0; }
    0          
752 0 0         if ((lo >> k) == 0) lo = UVCONST(1) << k;
753 0 0         if (hi > max_nth_almost_prime(k)) hi = max_nth_almost_prime(k);
754 0 0         if (lo > hi) { *list = 0; return 0; }
755              
756 0 0         if (k == 1) return range_prime_sieve(list, lo, hi);
757 0 0         if (k == 2) return range_semiprime_sieve(list, lo, hi);
758             /* if (k <= 5) return range_almost_prime_sieve(list, k, lo, hi); */
759              
760 0           minkap1 = 1 << (k-1);
761 0           lastprime = hi / minkap1; /* lastprime = prev_prime(lastprime+1); */
762              
763             {
764             UV i, Lsize;
765 0           UV *lkap1, nkap1=range_construct_almost_prime(&lkap1, k-1, minkap1, hi>>1);
766              
767             /* Now multiply through exhaustively. */
768 0           Lsize = nkap1*4 + 100;
769 0 0         New(0, L, Lsize, UV);
770              
771 0 0         START_DO_FOR_EACH_PRIME(2, lastprime) {
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
    0          
772 0 0         for (i = 0; i < nkap1; i++) {
773 0           UV prod = p * lkap1[i];
774 0 0         if (prod < lo) continue;
775 0 0         if (prod > hi) break;
776 0 0         if (count >= Lsize)
777 0           _tidy_list(&L, &Lsize, &count, 0);
778 0           L[count++] = prod;
779             }
780             } END_DO_FOR_EACH_PRIME
781 0           _tidy_list(&L, &Lsize, &count, 1);
782 0           Safefree(lkap1);
783             }
784 0           *list = L;
785 0           return count;
786             }
787              
788 3           UV range_almost_prime_sieve(UV** list, uint32_t k, UV slo, UV shi)
789             {
790             UV *S, Ssize, i, j, count;
791 3           const UV thresh_pred = 40;
792              
793 3 50         if (k == 0 || k >= BITS_PER_WORD) { *list = 0; return 0; }
    50          
794 3 50         if ((slo >> k) == 0) slo = UVCONST(1) << k;
795 3 50         if (shi > max_nth_almost_prime(k)) shi = max_nth_almost_prime(k);
796 3 50         if (slo > shi) { *list = 0; return 0; }
797              
798             #if 1
799 3 50         if (shi-slo+1 < thresh_pred) {
800 0           Ssize = 3 + (thresh_pred >> 1);
801 0 0         New(0, S, Ssize, UV);
802 0 0         for (i = 0, j = 0; i < shi-slo+1; i++)
803 0 0         if (is_almost_prime(k, slo+i))
804 0           S[j++] = slo+i;
805 0           *list = S;
806 0           return j;
807             }
808             #endif
809              
810 3 50         if (k == 1) return range_prime_sieve(list, slo, shi);
811 3 50         if (k == 2) return range_semiprime_sieve(list, slo, shi);
812              
813             /* See if we can reduce k.
814             * If for all possible kap from 1 to shi, ap(k,n) = 2*ap(k-1,n), then
815             * sieve for k-1 from lo/2 to hi/2+1.
816             * For large k this can continue even further so we might reduce a lot.
817             */
818             {
819 3           uint32_t r = reduce_k_for_n(k, shi);
820 3 50         if (r > 0) {
821 0           UV lo = (slo >> r) + (((slo >> r) << r) < slo);
822 0           UV hi = shi >> r;
823 0           count = range_almost_prime_sieve(&S, k-r, lo, hi);
824 0 0         for (i = 0; i < count; i++)
825 0           S[i] <<= r;
826 0           *list = S;
827 0           return count;
828             }
829             }
830              
831 3           Ssize = (almost_prime_count_approx(k,shi) - almost_prime_count_approx(k,slo) + 1) * 1.2 + 100;
832 3 50         if (Ssize > 10000000UL) Ssize = 10000000UL;
833 3 50         New(0, S, Ssize, UV);
834              
835             /* Do a range nfactor sieve in small windows, with one optimization.
836             *
837             * We know that we are looking for numbers with k factors, hence after
838             * looking for small factors we could get a remainder R as large as:
839             * 2 x 2 x ... x R where R could be prime or semiprime. Hence we can
840             * reduce the sieve limit somewhat. Effectively we are sieving to the
841             * maximum possible *second largest* factor for a k-almost-prime,
842             * allowing us to correctly decide whether R is prime or semiprime
843             * (if it has >= k factors).
844             *
845             * This isn't a big deal for small k, but it's a big impact for high k.
846             *
847             * I still think there should be a better way to do this for high k.
848             * Is there any way to do this just sieving to rootint(hi,k+1)?
849             * Given hi=10^6:
850             * k=3 => 97^3, 2x701^2, 2x2x249989
851             * k=4 => 31^4, 2x79^3, 2x2x499^2, 2x2x2x724991
852             */
853             {
854             unsigned char* nf;
855 3           UV const segsize = 65536*4;
856             UV *N, lo, hi, range;
857 3 50         UV kdiv = (k < 3) ? UVCONST(1) : (UVCONST(1) << (k-2));
858              
859 3           New(0, nf, segsize+1, unsigned char);
860 3 50         New(0, N, segsize+1, UV);
861 3           prime_precalc(isqrt(shi/kdiv));
862 3           count = 0;
863              
864 6 100         for (lo = slo; lo <= shi && lo >= slo; lo = hi+1) {
    50          
865 3           hi = lo+segsize-1;
866 3 50         if (hi > shi || hi < lo) hi = shi;
    0          
867 3           range = hi - lo + 1;
868 3           memset(nf, 0, range);
869 156 100         for (i = lo; i <= hi; i++) {
870 153 100         if (!(i&1) && i >= 2) {
    50          
871 78 50         const unsigned char nz = (unsigned char)ctz(i);
872 78           nf[i-lo] = nz;
873 78           N[i-lo] = UVCONST(1) << nz;
874             } else
875 75           N[i-lo] = 1;
876             }
877 381777 50         START_DO_FOR_EACH_PRIME(3, isqrt(hi/kdiv)) {
    50          
    100          
    50          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
878 372021           UV pk, maxpk = UV_MAX/p; \
879 372389 50         for (i = P_GT_LO_0(p,p,lo); i < range; i += p)
    100          
880 368           { N[i] *= p; nf[i]++; }
881 752679 100         for (pk = p*p; pk <= hi; pk *= p) {
882 380736 50         for (i = P_GT_LO_0(pk,pk,lo); i < range; i += pk)
    100          
883 78           { N[i] *= p; nf[i]++; }
884 380658 50         if (pk >= maxpk) break; /* Overflow protection */
885             }
886             } END_DO_FOR_EACH_PRIME
887 156 100         for (i = 0; i < range; i++) {
888 153 100         if (N[i] < (lo+i))
889 115           nf[i]++;
890 153 100         if (nf[i] == k) {
891 34 50         if (count >= Ssize)
892 0 0         Renew(S, Ssize += 10000, UV);
893 34           S[count++] = i+lo;
894             }
895             }
896             }
897 3           Safefree(N);
898 3           Safefree(nf);
899             }
900 3           *list = S;
901 3           return count;
902             }
903              
904             /* Algorithm from Trizen, May 2022 */
905 744           static void _genkap(UV lo, UV hi, uint32_t k, UV m, UV begp, UV **List, UV *Lpos, UV *Lsize) {
906 744 100         if (k == 1) {
907              
908 398           UV pos = *Lpos, size = *Lsize, *L = *List;
909 398           UV start = lo/m + (lo % m != 0), endp = hi/m;
910              
911 398 100         if (start > begp) begp = start;
912              
913 398 100         if (endp < 10000000U) {
914 1035 50         START_DO_FOR_EACH_PRIME(begp, endp) {
    100          
    100          
    100          
    100          
    100          
    100          
    50          
    100          
    50          
    100          
915 642 50         if (L != 0) {
916 642 50         if (pos >= size) Renew(L, size += 100000, UV);
    0          
917 642           L[pos] = m*p;
918             }
919 642           pos++;
920             } END_DO_FOR_EACH_PRIME
921             } else {
922             UV i, count, *list;
923 5           count = range_prime_sieve(&list, begp, endp);
924 5 50         if (L == 0) {
925 0           pos += count;
926             } else {
927 5 50         if ((pos + count - 1) >= size) Renew(L, size += (count + 100000), UV);
    0          
928 8 100         for (i = 0; i < count; i++)
929 3           L[pos++] = m * list[i];
930             }
931 5           Safefree(list);
932             }
933 398           *Lpos = pos;
934 398           *Lsize = size;
935 398           *List = L;
936              
937             } else {
938              
939             UV p, s;
940 31497 100         for (s = rootint(hi/m, k), p = begp; p <= s; p = next_prime(p)) {
941 31151           UV t = m * p;
942 31151 100         if ((lo/t + (lo % t != 0)) <= (hi/t))
943 732           _genkap(lo, hi, k-1, t, p, List, Lpos, Lsize);
944             }
945              
946             }
947 744           }
948              
949 24           UV generate_almost_primes(UV** list, uint32_t k, UV lo, UV hi) {
950 24           UV *L, Lpos = 0, Lsize, countest;
951              
952 24 50         if (k >= BITS_PER_WORD) { *list = 0; return 0; }
953 24 100         if ((lo >> k) == 0) lo = UVCONST(1) << k;
954 24 100         if (hi > max_nth_almost_prime(k)) hi = max_nth_almost_prime(k);
955 24 100         if (lo > hi) { *list = 0; return 0; }
956              
957             /* For these small k values, these are typically faster */
958 23 100         if (k == 0) { New(0,L,1,UV); L[0]=1; *list=L; return 1; }
959 20 100         if (k == 1) return range_prime_sieve(list, lo, hi);
960 17 100         if (k == 2) return range_semiprime_sieve(list, lo, hi);
961              
962             /* Large base with small range: better to sieve */
963 15 50         if ( (k >= 3 && hi >= 1e12 && (hi-lo) <= 5e6) ||
    100          
    50          
    50          
964 12 50         (k >= 3 && hi >= 1e13 && (hi-lo) <= 2e8) ||
    0          
    50          
965 12 50         (k >= 3 && hi >= 1e14 && (hi-lo) <= 4e8) )
    0          
966 3           return range_almost_prime_sieve(list, k, lo, hi);
967              
968             /* Optional: we could try reduce_k_for_n() here. */
969              
970 12           prime_precalc(10000000U);
971 12           countest = almost_prime_count_approx(k,hi) - almost_prime_count_approx(k,lo-1);
972 12 50         Lsize = (countest > 10000000U) ? 10000000U : countest+1000;
973              
974 12 50         New(0, L, Lsize, UV);
975 12           _genkap(lo, hi, k, 1, 2, &L, &Lpos, &Lsize);
976 12           sort_uv_array(L, Lpos);
977 12           *list = L;
978 12           return Lpos;
979             }
980              
981              
982             /******************************************************************************/
983             /* CHEN PRIMES */
984             /******************************************************************************/
985              
986             /* consider Chen(h,k) where p prime and bigomega(p+h) <= k */
987              
988             #if BITS_PER_WORD == 64
989             #define MAX_CHEN_PRIME UVCONST(18446744073709551437)
990             #else
991             #define MAX_CHEN_PRIME UVCONST(4294967291)
992             #endif
993              
994 202           bool is_chen_prime(UV n) {
995 202 100         if (n < 2 || n > MAX_CHEN_PRIME) return 0;
    50          
996 200 100         return (is_prime(n) && (is_prime(n+2) || is_semiprime(n+2)));
    100          
    100          
997             }
998              
999 36           UV next_chen_prime(UV n) {
1000 48 50         for ( n = next_prime(n); n != 0 && n < MAX_CHEN_PRIME; n = next_prime(n+2) )
    50          
1001 48 100         if (is_prime(n+2) || is_semiprime(n+2))
    100          
1002 36           return n;
1003 0           return 0;
1004             }