File Coverage

ramanujan_primes.c
Criterion Covered Total %
statement 167 183 91.2
branch 157 220 71.3
condition n/a
subroutine n/a
pod n/a
total 324 403 80.4


line stmt bran cond sub pod time code
1             #include
2             #include
3             #include
4              
5             #include "ptypes.h"
6             #define FUNC_log2floor 1
7             #include "util.h"
8             #define FUNC_is_prime_in_sieve 1
9             #include "prime_nth_count.h"
10             #include "sieve.h"
11             #include "ramanujan_primes.h"
12              
13             /******************************************************************************/
14             /* RAMANUJAN PRIMES */
15             /******************************************************************************/
16              
17             /* For Ramanujan prime estimates:
18             * - counts are done via inverse nth, so only one thing to tune.
19             * - For nth tables, upper values ok if too high, lower values ok if too low.
20             * - both upper & lower empirically tested to 175e9 (175 thousand million),
21             * with a return value of over 10^13.
22             */
23              
24             /* These are playing loose with Sondow/Nicholson/Noe 2011 theorem 4.
25             * The last value should be rigorously checked using actual R_n values. */
26             static const uint32_t small_ram_upper_idx[] = {
27             3971,3980,5219,5222,5225,5261,5264,5270,5276,5278,5324,5326,5554,7430,
28             7448,7451,8580,8584,8607,12589,12603,12620,12729,18119,18134,18174,18289,
29             18300,18401,18419,25799,27247,27267,28663,39635,40061,40366,45338,51320,
30             64439,65566,65829,84761,89055,104959,107852,146968,151755,186499,217258,
31             223956,270700,332195,347223,440804,508096,565039,768276,828377,1090285,
32             1277320,1568165,1896508,2375799,3300765,4162908,5124977,6522443,9298256,
33             11406250, 15873245, 21307556, 29899174, 40666215,
34             57180770, 81543888, 119596564, 177392936, 266391665,
35             411512446, 646331578, 1043239835, 1723380058, UVCONST(2919198776),
36             UVCONST(4294967295)
37             };
38             #define SMALL_NRAM_UPPER_MULT 2852
39             #define SMALL_NRAM_UPPER (sizeof(small_ram_upper_idx)/sizeof(small_ram_upper_idx[0]))
40              
41             #if BITS_PER_WORD == 64
42             static const UV large_ram_upper_idx[] = {
43             UVCONST( 2256197513), UVCONST( 2556868249), UVCONST( 2919198776),
44             /* 11071, 11070, 11069, 11068, 11067, 11066, 11065, 11064, 11063 */
45             UVCONST( 3371836636), UVCONST( 3874119737), UVCONST( 4467380631),
46             UVCONST( 5163817509), UVCONST( 5950413657), UVCONST( 6901033442),
47             UVCONST( 8015893438), UVCONST( 9322299866), UVCONST( 10845166831),
48             /* 11062, 11061, 11060, 11059, 11058, 11057, 11056, 11055, 11054 */
49             UVCONST( 12727569836), UVCONST( 14852585181), UVCONST( 17463419944),
50             UVCONST( 20585027534), UVCONST( 24252210453), UVCONST( 28704897522),
51             UVCONST( 34003499133), UVCONST( 40436019651), UVCONST( 48229247660),
52             /* 11053, 11052, 11051, 11050, 11049, 11048, 11047, 11046, 11045 */
53             UVCONST( 57558675911), UVCONST( 69028965312), UVCONST( 83015434548),
54             UVCONST( 100138535684), UVCONST( 121051505524), UVCONST( 146783829698),
55             UVCONST( 178727808587), UVCONST( 218113299173), UVCONST( 267104085772),
56             /* 11044, 11043, 11042, 11041, 11040, 11039, 11038, 11037, 11036 */
57             UVCONST( 328057281739), UVCONST( 404608665617), UVCONST( 500552556306),
58             UVCONST( 621794385742), UVCONST( 774739900202), UVCONST( 969943548548),
59             UVCONST( 1218276754392), UVCONST( 1536655221634), UVCONST( 1946308957195),
60             /* 11035, 11034, 11033, 11032, 11031, 11030, 11029, 11028, 11027 */
61             UVCONST( 2475456777850), UVCONST( 3162491651655), UVCONST( 4058282334559),
62             UVCONST( 5233096936468), UVCONST( 6776539822896), UVCONST( 8821085181511),
63             UVCONST( 11539712635284), UVCONST( 15171808426849), UVCONST( 20056581407599),
64             /* 11026, 11025, 11024, 11023, 11022, 11021, 11020, 11019, 11018 */
65             UVCONST( 26656864542121), UVCONST( 35627338984775), UVCONST( 47899755943330),
66             UVCONST( 64773009691258), UVCONST( 88134778026475), UVCONST(120680838280663),
67             UVCONST(166331208358410), UVCONST(230783974844445), UVCONST(322443487572932),
68             /* 11017, 11016, 11015, 11014, 11013, 11012, 11011, 11010, 11009 */
69             UVCONST(453738479744216), UVCONST(643248344602940), UVCONST(918867804392140),
70             UVCONST(1322953724888193),UVCONST(1920282116080684),
71             1.47*UVCONST(1920282116080684), /* Estimates for larger */
72             2.3*UVCONST(1920282116080684),
73             3.4*UVCONST(1920282116080684),
74             5.1*UVCONST(1920282116080684),
75             7.9*UVCONST(1920282116080684),
76             12.2*UVCONST(1920282116080684),
77             };
78             #define LARGE_NRAM_UPPER_MULT 11075
79             #define LARGE_NRAM_UPPER (sizeof(large_ram_upper_idx)/sizeof(large_ram_upper_idx[0]))
80             #endif
81              
82 1280           UV nth_ramanujan_prime_upper(UV n) {
83             UV i, mult, res;
84              
85 1280 100         if (n <= 2) return (n==0) ? 0 : (n==1) ? 2 : 11;
    50          
    100          
86 1273           res = nth_prime_upper(3*n);
87              
88 1273 50         if (n < UVCONST(2256197512) || BITS_PER_WORD < 64) {
89             /* While p_3n is a complete upper bound, Rp_n tends to p_2n, and
90             * SNN(2011) theorem 4 shows how we can find (m,c) values where m < 1,
91             * Rn < m*p_3n for all n > c. Here we use various quantized m values
92             * and the table gives us c values where it applies. */
93 1273 100         if (n < 20) mult = 3580;
94 1047 100         else if (n < 98) mult = 3340;
95 116 100         else if (n < 1580) mult = 3040;
96 104 100         else if (n < 3242) mult = 2885;
97             else {
98 5729 50         for (i = 0; i < SMALL_NRAM_UPPER; i++)
99 5729 100         if (small_ram_upper_idx[i] > n)
100 103           break;
101 103           mult = SMALL_NRAM_UPPER_MULT-i;
102             }
103 1273 50         if (res > (UV_MAX/mult)) res = (UV) (((long double) mult / 4096.0L) * res);
104 1273           else res = (res * mult) >> 12;
105             #if BITS_PER_WORD == 64
106             } else {
107 0 0         for (i = 0; i < LARGE_NRAM_UPPER; i++)
108 0 0         if (large_ram_upper_idx[i] > n)
109 0           break;
110 0           mult = (LARGE_NRAM_UPPER_MULT-i);
111 0 0         if (res > (UV_MAX/mult)) res = (UV) (((long double) mult / 16384.0L) * res);
112 0           else res = (res * mult) >> 14;
113             #endif
114             }
115 1273 100         if (n > 43 && n < 10000) {
    100          
116             /* Calculate upper bound using Srinivasan and ArĂ©s 2017 */
117             /* TODO We should construct a tighter bound like this. */
118 526           double s = (2 * (double)n) * (1.0L + 1.0L/ramanujan_sa_gn(n));
119 526           UV ps = nth_prime_upper( (UV) s );
120 526 100         if (ps < res)
121 24           res = ps;
122             }
123 1273           return res;
124             }
125             static const uint32_t small_ram_lower_idx[] = {
126             2786, 2801, 4275, 5935, 6107, 8797, 9556, 13314, 13641, 20457, 23745,
127             34432, 50564, 69194, 97434, 149399, 224590, 337116, 514260, 804041,
128             1317612, 2340461, 4332796, 8393680, 17227225, 38996663, 94437897,
129             253560792, 763315838, UVCONST(2663598260), UVCONST(4294967295)
130             };
131             #define SMALL_NRAM_LOWER_MULT 557
132             #define SMALL_NRAM_LOWER (sizeof(small_ram_lower_idx)/sizeof(small_ram_lower_idx[0]))
133              
134             #if BITS_PER_WORD == 64
135             static const UV large_ram_lower_idx[] = {
136             UVCONST( 2267483962), UVCONST( 2663598260), UVCONST( 3152476871),
137             UVCONST( 3742932857), UVCONST( 4446913643), UVCONST( 5298293978),
138             UVCONST( 6318053149), UVCONST( 7608807497), UVCONST( 9140758346),
139             UVCONST( 11015956390), UVCONST( 13351265915), UVCONST( 16199147294),
140             /* 4213, 4212, 4211, 4210, 4209, 4208, 4207, 4206, 4205 */
141             UVCONST( 19739499402), UVCONST( 24137542585), UVCONST( 29629560254),
142             UVCONST( 36435870727), UVCONST( 45085624406), UVCONST( 55940244390),
143             UVCONST( 69713814138), UVCONST( 87221199999), UVCONST( 109606558728),
144             /* 4204, 4203, 4202, 4201, 4200, 4199, 4198, 4197, 4196 */
145             UVCONST( 138227790751), UVCONST( 175290761423), UVCONST( 223132516788),
146             UVCONST( 285315117360), UVCONST( 366761235749), UVCONST( 473606049986),
147             UVCONST( 614858505562), UVCONST( 802552362351), UVCONST( 1052957884730),
148             /* 4195, 4194, 4193, 4192, 4191, 4190, 4189, 4188, 4187 */
149             UVCONST( 1389550174208), UVCONST( 1843854433659), UVCONST( 2461728402552),
150             UVCONST( 3306766457564), UVCONST( 4469341663210), UVCONST( 6080948095909),
151             UVCONST( 8329279118918), UVCONST( 11488848759561), UVCONST( 15959135388235),
152             /* 4186, 4185, 4184, 4183, 4182, 4181, 4180, 4179, 4178 */
153             UVCONST( 22336622435614), UVCONST( 31501671598985), UVCONST( 44779902229212),
154             UVCONST( 64180867011184), UVCONST( 92772523880955), UVCONST(135282253437392),
155             UVCONST(199079826917291), UVCONST(295746797998912), UVCONST(443667118326600),
156             /* 4177, 4176, 4175, 4174, 4173, 4172, 4171, 4170, 4169 */
157             UVCONST(672350086039900),UVCONST(1029719394152693),UVCONST(1594365662292999),
158             1.55*UVCONST(1594365662292999), /* estimates here and further */
159             2.45*UVCONST(1594365662292999),
160             3.90*UVCONST(1594365662292999),
161             6.30*UVCONST(1594365662292999),
162             10.4*UVCONST(1594365662292999),
163             17.2*UVCONST(1594365662292999),
164             };
165             #define LARGE_NRAM_LOWER_MULT 4225
166             #define LARGE_NRAM_LOWER (sizeof(large_ram_lower_idx)/sizeof(large_ram_lower_idx[0]))
167             #endif
168              
169 1295           UV nth_ramanujan_prime_lower(UV n) {
170             UV res, i, mult;
171 1295 100         if (n <= 2) return (n==0) ? 0 : (n==1) ? 2 : 11;
    50          
    100          
172              
173 1288           res = nth_prime_lower(2*n);
174              
175 1288 50         if (n < UVCONST(2267483962) || BITS_PER_WORD < 64) {
176 3201 50         for (i = 0; i < SMALL_NRAM_LOWER; i++)
177 3201 100         if (small_ram_lower_idx[i] > n)
178 1288           break;
179 1288           mult = (SMALL_NRAM_LOWER_MULT-i);
180 1288 50         if (res > (UV_MAX/mult)) res = (UV) (((long double) mult / 512.0L) * res);
181 1288           else res = (res * mult) >> 9;
182             #if BITS_PER_WORD == 64
183             } else {
184 0 0         if (n < large_ram_lower_idx[LARGE_NRAM_LOWER-1]) {
185 0 0         for (i = 0; i < LARGE_NRAM_LOWER; i++)
186 0 0         if (large_ram_lower_idx[i] > n)
187 0           break;
188 0           mult = (LARGE_NRAM_LOWER_MULT-i);
189 0 0         if (res > (UV_MAX/mult)) res = (UV) (((long double) mult / 4096.0L) * res);
190 0           else res = (res * mult) >> 12;
191             }
192             #endif
193             }
194 1288           return res;
195             }
196              
197             /* An advantage of making these binary searches on the inverse is that we
198             * don't have to tune them separately, and nothing changes if the prime
199             * count bounds are modified. We do need to keep up to date with any
200             * changes to nth_prime_{lower,upper} however. */
201              
202 251           UV ramanujan_prime_count_lower(UV n) {
203             UV lo, hi;
204 251 100         if (n < 29) return (n < 2) ? 0 : (n < 11) ? 1 : (n < 17) ? 2 : 3;
    50          
    100          
    100          
205             /* Binary search on nth_ramanujan_prime_upper */
206             /* We know we're between p_2n and p_3n, probably close to the former. */
207 233           lo = prime_count_lower(n)/3;
208 233           hi = prime_count_upper(n) >> 1;
209 1158 100         while (lo < hi) {
210 925           UV mid = lo + (hi-lo)/2;
211 925 100         if (nth_ramanujan_prime_upper(mid) < n) lo = mid+1;
212 476           else hi = mid;
213             }
214 233           return lo-1;
215             }
216 251           UV ramanujan_prime_count_upper(UV n) {
217             /* return prime_count_upper(n) >> 1; */ /* Simple bound */
218             UV lo, hi;
219 251 100         if (n < 29) return (n < 2) ? 0 : (n < 11) ? 1 : (n < 17) ? 2 : 3;
    50          
    100          
    100          
220             /* Binary search on nth_ramanujan_prime_upper */
221             /* We know we're between p_2n and p_3n, probably close to the former. */
222 235           lo = prime_count_lower(n)/3;
223 235           hi = prime_count_upper(n) >> 1;
224 1183 100         while (lo < hi) {
225 948           UV mid = lo + (hi-lo)/2;
226 948 100         if (nth_ramanujan_prime_lower(mid) < n) lo = mid+1;
227 361           else hi = mid;
228             }
229 235           return lo-1;
230             }
231              
232             /* Return array of first n ramanujan primes. Use Noe's algorithm. */
233 8           UV* n_ramanujan_primes(UV n) {
234             UV max, k, s, *L;
235             unsigned char* sieve;
236 8           max = nth_ramanujan_prime_upper(n); /* Rn <= max, so we can sieve to there */
237 8 50         if (_XS_get_verbose() >= 2) { printf("sieving to %"UVuf" for first %"UVuf" Ramanujan primes\n", max, n); fflush(stdout); }
238 8 50         Newz(0, L, n, UV);
239 8           L[0] = 2;
240 8           sieve = sieve_erat30(max);
241 884 100         for (s = 0, k = 7; k <= max; k += 2) {
242 876 100         if (is_prime_in_sieve(sieve, k)) s++;
243 876 100         if (s < n) L[s] = k+1;
244 876 100         if ((k & 3) == 1 && is_prime_in_sieve(sieve, (k+1)>>1)) s--;
    100          
245 876 100         if (s < n) L[s] = k+2;
246             }
247 8           Safefree(sieve);
248 8           return L;
249             }
250              
251 259           UV* n_range_ramanujan_primes(UV nlo, UV nhi) {
252             UV mink, maxk, k, s, *L;
253 259           int verbose = _XS_get_verbose();
254              
255 259 50         if (nlo == 0) nlo = 1;
256 259 50         if (nhi == 0) nhi = 1;
257              
258             /* If we're starting from 1, just do single monolithic sieve */
259 259 100         if (nlo == 1) return n_ramanujan_primes(nhi);
260              
261 251 50         Newz(0, L, nhi-nlo+1, UV);
262 251 50         if (nlo <= 1 && nhi >= 1) L[1-nlo] = 2;
    0          
263 251 100         if (nlo <= 2 && nhi >= 2) L[2-nlo] = 11;
    50          
264 251 100         if (nhi < 3) return L;
265              
266 250           mink = nth_ramanujan_prime_lower(nlo) - 1;
267 250           maxk = nth_ramanujan_prime_upper(nhi) + 1;
268              
269 250 100         if (mink < 15) mink = 15;
270 250 100         if (mink % 2 == 0) mink--;
271 250 50         if (verbose >= 2) { printf("Rn[%"UVuf"] to Rn[%"UVuf"] Noe's: %"UVuf" to %"UVuf"\n", nlo, nhi, mink, maxk); fflush(stdout); }
272              
273 250           s = 1 + prime_count(2,mink-2) - prime_count(2,(mink-1)>>1);
274             {
275 250           unsigned char *segment, *seg2 = 0;
276 250           void* ctx = start_segment_primes(mink, maxk, &segment);
277 250           UV seg_base, seg_low, seg_high, new_size, seg2beg, seg2end, seg2size = 0;
278 500 100         while (next_segment_primes(ctx, &seg_base, &seg_low, &seg_high)) {
279 250           seg2beg = 30 * (((seg_low+1)>>1)/30);
280 250           seg2end = 30 * ((((seg_high+1)>>1)+29)/30);
281 250           new_size = (seg2end - seg2beg)/30 + 1;
282 250 50         if (new_size > seg2size) {
283 250 50         if (seg2size > 0) Safefree(seg2);
284 250           New(0, seg2, new_size, unsigned char);
285 250           seg2size = new_size;
286             }
287 250           (void) sieve_segment(seg2, seg2beg/30, seg2end/30);
288 197451 100         for (k = seg_low; k <= seg_high; k += 2) {
289 197201 100         if (is_prime_in_sieve(segment, k-seg_base)) s++;
290 197201 100         if (s >= nlo && s <= nhi) L[s-nlo] = k+1;
    100          
291 197201 100         if ((k & 3) == 1 && is_prime_in_sieve(seg2, ((k+1)>>1)-seg2beg)) s--;
    100          
292 197201 100         if (s >= nlo && s <= nhi) L[s-nlo] = k+2;
    100          
293             }
294             }
295 250           end_segment_primes(ctx);
296 250           Safefree(seg2);
297             }
298 250 50         if (verbose >= 2) { printf("Generated %"UVuf" Ramanujan primes from %"UVuf" to %"UVuf"\n", nhi-nlo+1, L[0], L[nhi-nlo]); fflush(stdout); }
299 250           return L;
300             }
301              
302 75           UV nth_ramanujan_prime(UV n) {
303             UV rn, *L;
304 75 100         if (n <= 2) return (n == 0) ? 0 : (n == 1) ? 2 : 11;
    50          
    100          
305 73           L = n_range_ramanujan_primes(n, n);
306 73           rn = L[0];
307 73           Safefree(L);
308 73           return rn;
309             }
310              
311             /* Returns array of Ram primes between low and high, results from first->last */
312 175           UV* ramanujan_primes(UV* first, UV* last, UV low, UV high)
313             {
314             UV nlo, nhi, *L, lo, hi, mid;
315              
316 175 50         if (high < 2 || high < low) return 0;
    50          
317 175 50         if (low < 2) low = 2;
318              
319 175           nlo = ramanujan_prime_count_lower(low);
320 175           nhi = ramanujan_prime_count_upper(high);
321 175           L = n_range_ramanujan_primes(nlo, nhi);
322              
323             /* Search for first entry in range */
324 689 100         for (lo = 0, hi = nhi-nlo+1; lo < hi; ) {
325 514           mid = lo + (hi-lo)/2;
326 514 100         if (L[mid] < low) lo = mid+1;
327 274           else hi = mid;
328             }
329 175           *first = lo;
330             /* Search for last entry in range */
331 548 100         for (hi = nhi-nlo+1; lo < hi; ) {
332 373           mid = lo + (hi-lo)/2;
333 373 100         if (L[mid] <= high) lo = mid+1;
334 285           else hi = mid;
335             }
336 175           *last = lo-1;
337 175           return L;
338             }
339              
340 984           int is_ramanujan_prime(UV n) {
341             UV beg, end, *L;
342              
343 984 100         if (!is_prime(n)) return 0;
344 166 100         if (n < 17) return (n == 2 || n == 11);
    100          
    100          
345              
346             /* Generate Ramanujan primes and see if we're in the list. Slow. */
347 160           L = ramanujan_primes(&beg, &end, n, n);
348 160           Safefree(L);
349 984           return (beg <= end);
350             }
351              
352 2           UV ramanujan_prime_count_approx(UV n)
353             {
354             /* Binary search on nth_ramanujan_prime_approx */
355             UV lo, hi;
356 2 50         if (n < 29) return (n < 2) ? 0 : (n < 11) ? 1 : (n < 17) ? 2 : 3;
    0          
    0          
    0          
357 2           lo = ramanujan_prime_count_lower(n);
358 2           hi = ramanujan_prime_count_upper(n);
359 23 100         while (lo < hi) {
360 21           UV mid = lo + (hi-lo)/2;
361 21 100         if (nth_ramanujan_prime_approx(mid) < n) lo = mid+1;
362 14           else hi = mid;
363             }
364 2           return lo-1;
365             }
366              
367 23           UV nth_ramanujan_prime_approx(UV n)
368             {
369 23           UV lo = nth_ramanujan_prime_lower(n), hi = nth_ramanujan_prime_upper(n);
370             /* Our upper bounds come out much closer, so weight toward them. */
371 23 50         double weight = (n <= UVCONST(4294967295)) ? 1.62 : 1.51;
372 23           return lo + weight * ((hi-lo) >> 1);
373             }
374              
375             #if BITS_PER_WORD == 64
376             #define RAMPC2 56
377             static const UV ramanujan_counts_pow2[RAMPC2+1] = {
378             0, 1, 1, 1, 2, 4, 7, 13, 23, 42, 75, 137, 255, 463, 872, 1612,
379             3030, 5706, 10749, 20387, 38635, 73584, 140336, 268216, 513705,
380             985818, 1894120, 3645744, 7027290, 13561906, 26207278, 50697533,
381             98182656, 190335585, 369323301, 717267167,
382             UVCONST( 1394192236), UVCONST( 2712103833), UVCONST( 5279763823),
383             UVCONST( 10285641777), UVCONST( 20051180846), UVCONST( 39113482639),
384             UVCONST( 76344462797), UVCONST( 149100679004), UVCONST( 291354668495),
385             UVCONST( 569630404447), UVCONST( 1114251967767), UVCONST( 2180634225768),
386             UVCONST( 4269555883751), UVCONST( 8363243713305), UVCONST( 16388947026629),
387             UVCONST( 32129520311897), UVCONST( 63012603695171), UVCONST(123627200537929),
388             UVCONST(242637500756376), UVCONST(476379740340417), UVCONST(935609435783647) };
389             #else
390             #define RAMPC2 31 /* input limited */
391             static const UV ramanujan_counts_pow2[RAMPC2+1] = {
392             0, 1, 1, 1, 2, 4, 7, 13, 23, 42, 75, 137, 255, 463, 872, 1612,
393             3030, 5706, 10749, 20387, 38635, 73584, 140336, 268216, 513705,
394             985818, 1894120, 3645744, 7027290, 13561906, 26207278, 50697533 };
395             #endif
396              
397 12           static UV _ramanujan_prime_count(UV n) {
398 12 50         UV i, v, rn, *L, window, swin, ewin, wlen, log2 = log2floor(n), winmult = 1;
399              
400 12 50         if (n <= 10) return (n < 2) ? 0 : 1;
401              
402             /* We have some perfect powers of 2 in our table */
403 12 100         if ((n & (n-1)) == 0 && log2 <= RAMPC2)
    50          
404 1           return ramanujan_counts_pow2[log2];
405              
406 11 50         if (_XS_get_verbose()) { printf("ramanujan_prime_count calculating Pi(%lu)\n",n); fflush(stdout); }
407 11           v = prime_count(2,n) - prime_count(2,n >> 1);
408              
409             /* For large enough n make a slightly bigger window */
410 11 50         if (n > 1000000000U) winmult = 16;
411              
412             while (1) {
413 11           window = 20 * winmult;
414 11 100         swin = (v <= window) ? 1 : v-window;
415 11           ewin = v+window;
416 11           wlen = ewin-swin+1;
417 11           L = n_range_ramanujan_primes(swin, ewin);
418 11 50         if (L[0] < n && L[wlen-1] > n) {
    50          
419             /* Naive linear search from the start. */
420 191 50         for (i = 1; i < wlen; i++)
421 191 100         if (L[i] > n && L[i-1] <= n)
    50          
422 11           break;
423 11 50         if (i < wlen) break;
424             }
425 0           winmult *= 2;
426 0 0         if (_XS_get_verbose()) { printf(" ramanujan_prime_count increasing window\n"); fflush(stdout); }
427 0           }
428 11           rn = swin + i - 1;
429 11           Safefree(L);
430 11           return rn;
431             }
432              
433 10           UV ramanujan_prime_count(UV lo, UV hi)
434             {
435             UV count;
436              
437 10 50         if (hi < 2 || hi < lo) return 0;
    50          
438              
439             #if 1
440 10           count = _ramanujan_prime_count(hi);
441 10 100         if (lo > 2)
442 2           count -= _ramanujan_prime_count(lo-1);
443             #else
444             {
445             UV beg, end, *L;
446             /* Generate all Rp from lo to hi */
447             L = ramanujan_primes(&beg, &end, lo, hi);
448             count = (L && end >= beg) ? end-beg+1 : 0;
449             Safefree(L);
450             }
451             #endif
452 10           return count;
453             }