Skip to content

Commit 8901e77

Browse files
authored
Added 32-bit and 64-bit prime_less_than_next_pow_2_or_1 functions (#5)
1 parent b7177bc commit 8901e77

File tree

13 files changed

+261
-1
lines changed

13 files changed

+261
-1
lines changed

internals/primes/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
add_conventional_executable(primes)

internals/primes/program/main.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#include <cinttypes>
2+
#include <cmath>
3+
#include <cstdint>
4+
#include <cstdio>
5+
#include <vector>
6+
7+
//
8+
9+
static uint64_t bit(int i) { return static_cast<uint64_t>(1) << i; }
10+
11+
static uint64_t bits(int n) { return bit(n) * 2 - 1; }
12+
13+
//
14+
15+
static bool is_prime(uint64_t n) {
16+
if (n <= 3)
17+
return n > 1;
18+
else if (n % 2 == 0 || n % 3 == 0)
19+
return false;
20+
else
21+
for (uint64_t i = 5, m = static_cast<uint64_t>(sqrt(n) + 1); i <= m; i += 6)
22+
if (n % i == 0 || n % (i + 2) == 0)
23+
return false;
24+
return true;
25+
}
26+
27+
static std::vector<uint64_t> primes_less_than_pow_2(int m) {
28+
std::vector<uint64_t> results;
29+
results.reserve(64);
30+
results.push_back(1);
31+
for (int i = 1; i < m; ++i) {
32+
uint64_t n = bits(i);
33+
while (!is_prime(n))
34+
n -= 2;
35+
results.push_back(n);
36+
}
37+
return results;
38+
}
39+
40+
//
41+
42+
static void print_table(int n_bits,
43+
int keep_bits,
44+
std::vector<uint64_t> table,
45+
uint64_t de_bruijn_sequence) {
46+
struct entry {
47+
int i;
48+
uint64_t n;
49+
uint64_t v;
50+
};
51+
52+
std::vector<entry> reindexed;
53+
reindexed.resize(n_bits);
54+
55+
for (int i = 0; i < n_bits; ++i) {
56+
uint64_t n = bits(i);
57+
int j = static_cast<int>((n * de_bruijn_sequence >> (n_bits - keep_bits)) &
58+
bits(keep_bits - 1));
59+
uint64_t v = table[i];
60+
reindexed[j] = entry{i, n, v};
61+
}
62+
63+
for (const auto &e : reindexed)
64+
fprintf(
65+
stdout, "0x%016" PRIx64 " - 0x%016" PRIx64 ", // %2d\n", e.n, e.v, e.i);
66+
}
67+
68+
int main() {
69+
auto primes = primes_less_than_pow_2(64);
70+
71+
print_table(32, 5, primes, 0x07c4acdd);
72+
fprintf(stdout, "\n");
73+
print_table(64, 6, primes, 0x03f08a4c6acb9dbd);
74+
75+
return 0;
76+
}
File renamed without changes.
File renamed without changes.
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#include "dumpster_v1/primes.hpp"
2+
3+
#include "testing_v1/test.hpp"
4+
5+
using namespace testing_v1;
6+
7+
#define VERIFY_IS_PRIME_OR_1 0
8+
9+
#if VERIFY_IS_PRIME_OR_1
10+
#include <cmath>
11+
12+
static bool is_prime(uint64_t n) {
13+
if (n <= 3)
14+
return n > 1;
15+
else if (n % 2 == 0 || n % 3 == 0)
16+
return false;
17+
else
18+
for (uint64_t i = 5, m = static_cast<uint64_t>(sqrt(n) + 1); i <= m; i += 6)
19+
if (n % i == 0 || n % (i + 2) == 0)
20+
return false;
21+
return true;
22+
}
23+
#endif
24+
25+
template <class T> static void test() {
26+
for (int i = 0; i < static_cast<int>(sizeof(T) * 8); ++i) {
27+
T n = static_cast<T>(1) << i;
28+
T p = dumpster_v1::prime_less_than_next_pow_2_or_1(n);
29+
#if VERIFY_IS_PRIME_OR_1
30+
verify(1 == p || is_prime(p));
31+
#endif
32+
verify(n <= p && p <= n * 2 - 1);
33+
}
34+
}
35+
36+
auto primes_test = test([]() {
37+
test<uint32_t>();
38+
test<uint64_t>();
39+
});
File renamed without changes.

provides/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
add_conventional_library(dumpster_v1)
2-
target_link_libraries(dumpster_v1 INTERFACE polyfill_v1)
2+
target_link_libraries(dumpster_v1 PUBLIC polyfill_v1)

0 commit comments

Comments
 (0)