Legendre prime counting function: Difference between revisions
→{{header|C}}: Aligned with changes to V example of which it is a translation.
GordonBGood (talk | contribs) (→{{header|Vlang}}: correction to increase precision to extend range...) |
(→{{header|C}}: Aligned with changes to V example of which it is a translation.) |
||
Line 38:
Using fixed width types so requires C99 or later.
Surprisingly only half as fast as Go on the same machine (GCC -O3 Ubuntu 22.04) for a billion numbers.
However, the position is reversed if we let it run through to a trillion numbers - about 100 ms for C compared to 160 ms for Go.
<syntaxhighlight lang="c">#include <stdio.h>
#include <math.h>
Line 47 ⟶ 49:
const uint8_t masks[8] = {1, 2, 4, 8, 16, 32, 64, 128};
#define half(n) ((int64_t)((n) - 1) >> 1)
#define divide(nm, d) ((
int64_t countPrimes(uint64_t n) {
if (n < 3) return (n < 2) ? 0 : 1;
int arrlen = (int)(mxndx + 1);
int i;▼
uint32_t *smalls = malloc(arrlen * 4);
uint32_t *roughs = malloc(arrlen * 4);
int64_t *larges = malloc(arrlen * 8);
for (int i = 0; i < arrlen; ++i) {
smalls[i] = (uint32_t)i;
roughs[i] = (uint32_t)(i + i + 1);
larges[i] = (int64_t)((n/(uint64_t)(i + i + 1) - 1) / 2);
}
int cullbuflen = (int)((mxndx + 8) / 8);
uint8_t *cullbuf = calloc(cullbuflen, 1);
int rilmt = arrlen;
for (int64_t i = 1; ; ++i) {
if (sqri > mxndx) break;
if (cullbuf[i >> 3] & masks[i & 7]) continue;
cullbuf[i >> 3] |= masks[i & 7];
for (int64_t c = sqri; c < (int64_t)arrlen; c += (int64_t)bp) {
int nri = 0;
for (int ori = 0; ori < rilmt; ++ori) {
if (cullbuf[
int64_t t = (d <= rtlmt) ? larges[(
(int64_t)smalls[half(divide(n,
larges[nri] = larges[ori] - t +
roughs[nri] =
nri++;
}
for (uint64_t pm = (rtlmt/bp - 1) | 1; pm >= bp; pm -= 2) {
uint32_t c = smalls[pm >> 1];
for ( ; si >= (int64_t)e; --si) smalls[si] -= c - (uint32_t)nbps;
}
rilmt = nri;
Line 104 ⟶ 106:
uint64_t p = (uint64_t)roughs[ri];
uint64_t m = n / p;
int ei = (int)smalls[half((
if (ei <= ri) break;
ans -= (int64_t)((ei - ri) * (nbps + ri - 1));
Line 143 ⟶ 145:
10^9 50847534
Took 0.
</pre>
|