Skip to content

Commit e4fbc61

Browse files
separating prime and fubonacci header
1 parent e96c6e2 commit e4fbc61

File tree

4 files changed

+103
-98
lines changed

4 files changed

+103
-98
lines changed

discrete/include/numbers.hxx renamed to discrete/include/fibonacci.hxx

Lines changed: 0 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@
2121
#pragma once
2222

2323
#include <algorithm>
24-
#include <cmath>
2524
#include <cstddef>
2625
#include <cstdint>
2726
#include <string>
28-
#include <thread>
2927
#include <type_traits>
3028
#include <vector>
3129

@@ -36,100 +34,6 @@
3634
template <typename T, typename Ret = T>
3735
using enable_if_integral = typename std::enable_if<
3836
std::is_integral<T>::value && !std::is_same<T, bool>::value, Ret>::type;
39-
template <typename T, typename Ret = T>
40-
using enable_if_arithmetic = typename std::enable_if<
41-
std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, Ret>::type;
42-
43-
template <typename T, enable_if_arithmetic<T> = 0>
44-
class Prime {
45-
private:
46-
std::vector<T> lastResults;
47-
T lastLimit = 0;
48-
T lastSize = 0;
49-
inline static int maxThread = std::thread::hardware_concurrency();
50-
51-
void main_sieve(std::vector<uint64_t> &sieve, T limit, int offset) {
52-
for (T p = 3 + offset * 2; p * p <= limit; p += 2 * maxThread) {
53-
const size_t i = (p - 3) >> 1;
54-
if (!(sieve[i >> 6] & (1ULL << (i & 63)))) continue;
55-
for (T j = p * p; j <= limit; j += 2 * p) {
56-
const size_t idx = (j - 3) >> 1;
57-
sieve[idx >> 6] &= ~(1ULL << (idx & 63));
58-
}
59-
}
60-
}
61-
62-
std::vector<uint64_t> create_sieve(T limit) {
63-
if (limit < 3) return {};
64-
const size_t num_odds = ((limit - 3) >> 1) + 1;
65-
const size_t array_size = (num_odds + 63) >> 6;
66-
std::vector<uint64_t> sieve(array_size, uint64_t(~0));
67-
std::vector<std::thread> threads;
68-
for (int i = 1; i < maxThread; ++i)
69-
threads.emplace_back(
70-
[this, &sieve, limit, i]() { main_sieve(sieve, limit, i); });
71-
main_sieve(sieve, limit, 0);
72-
for (auto &t : threads) t.join();
73-
return sieve;
74-
}
75-
76-
T estimate_limit_from_size(size_t size) {
77-
if (size < 6) return (1 << 4) - 1;
78-
double n = static_cast<double>(size);
79-
return static_cast<T>(n * (std::log(n) + std::log(std::log(n)))) + 10;
80-
}
81-
82-
public:
83-
std::vector<T> from_size(size_t size) {
84-
if (size <= lastSize) {
85-
this->lastResults.resize(size);
86-
return this->lastResults;
87-
}
88-
if (size == 0) return {};
89-
std::vector<T> primes;
90-
primes.push_back(2);
91-
if (size == 1) return primes;
92-
T limit = estimate_limit_from_size(size);
93-
lastLimit = limit;
94-
auto sieve = create_sieve(limit);
95-
const size_t num_odds = ((limit - 3) >> 1) + 1;
96-
97-
for (size_t i = 0; i < num_odds && primes.size() < size; ++i)
98-
if (sieve[i >> 6] & (1ULL << (i & 63))) primes.emplace_back(3 + 2 * i);
99-
100-
lastResults = primes;
101-
return primes;
102-
}
103-
104-
std::vector<T> from_range_limit(T limit) {
105-
if (limit == lastLimit) return this->lastResults;
106-
std::vector<T> primes;
107-
if (limit < 2) return primes;
108-
primes.push_back(2);
109-
if (limit < 3) return primes;
110-
lastLimit = limit;
111-
auto sieve = create_sieve(limit);
112-
const size_t num_odds = ((limit - 3) >> 1) + 1;
113-
114-
for (size_t i = 0; i < num_odds; ++i)
115-
if (sieve[i >> 6] & (1ULL << (i & 63))) primes.emplace_back(3 + 2 * i);
116-
117-
lastResults = primes;
118-
return primes;
119-
}
120-
121-
bool is_prime(T n) {
122-
if (n <= 1) return false;
123-
if (n == 2) return true;
124-
if ((n & 1) == 0) return false;
125-
T sqrt_n = static_cast<T>(std::sqrt(n));
126-
auto sieve = from_range_limit(sqrt_n);
127-
for (T p : sieve)
128-
if (n % p == 0) return false;
129-
return true;
130-
}
131-
static int max_thread() { return Prime::maxThread; }
132-
};
13337

13438
class Fibonacci {
13539
private:

discrete/include/prime.hxx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
#pragma once
2+
3+
#include <type_traits>
4+
#include <vector>
5+
#include <cstdint>
6+
#include <thread>
7+
8+
template <typename T, typename Ret = T>
9+
using enable_if_arithmetic = typename std::enable_if<
10+
std::is_arithmetic<T>::value && !std::is_same<T, bool>::value, Ret>::type;
11+
12+
template <typename T, enable_if_arithmetic<T> = 0>
13+
class Prime {
14+
private:
15+
std::vector<T> lastResults;
16+
T lastLimit = 0;
17+
T lastSize = 0;
18+
inline static int maxThread = std::thread::hardware_concurrency();
19+
20+
void main_sieve(std::vector<uint64_t> &sieve, T limit, int offset) {
21+
for (T p = 3 + offset * 2; p * p <= limit; p += 2 * maxThread) {
22+
const size_t i = (p - 3) >> 1;
23+
if (!(sieve[i >> 6] & (1ULL << (i & 63)))) continue;
24+
for (T j = p * p; j <= limit; j += 2 * p) {
25+
const size_t idx = (j - 3) >> 1;
26+
sieve[idx >> 6] &= ~(1ULL << (idx & 63));
27+
}
28+
}
29+
}
30+
31+
std::vector<uint64_t> create_sieve(T limit) {
32+
if (limit < 3) return {};
33+
const size_t num_odds = ((limit - 3) >> 1) + 1;
34+
const size_t array_size = (num_odds + 63) >> 6;
35+
std::vector<uint64_t> sieve(array_size, uint64_t(~0));
36+
std::vector<std::thread> threads;
37+
for (int i = 1; i < maxThread; ++i)
38+
threads.emplace_back(
39+
[this, &sieve, limit, i]() { main_sieve(sieve, limit, i); });
40+
main_sieve(sieve, limit, 0);
41+
for (auto &t : threads) t.join();
42+
return sieve;
43+
}
44+
45+
T estimate_limit_from_size(size_t size) {
46+
if (size < 6) return (1 << 4) - 1;
47+
double n = static_cast<double>(size);
48+
return static_cast<T>(n * (std::log(n) + std::log(std::log(n)))) + 10;
49+
}
50+
51+
public:
52+
std::vector<T> from_size(size_t size) {
53+
if (size <= lastSize) {
54+
this->lastResults.resize(size);
55+
return this->lastResults;
56+
}
57+
if (size == 0) return {};
58+
std::vector<T> primes;
59+
primes.push_back(2);
60+
if (size == 1) return primes;
61+
T limit = estimate_limit_from_size(size);
62+
lastLimit = limit;
63+
auto sieve = create_sieve(limit);
64+
const size_t num_odds = ((limit - 3) >> 1) + 1;
65+
66+
for (size_t i = 0; i < num_odds && primes.size() < size; ++i)
67+
if (sieve[i >> 6] & (1ULL << (i & 63))) primes.emplace_back(3 + 2 * i);
68+
69+
lastResults = primes;
70+
return primes;
71+
}
72+
73+
std::vector<T> from_range_limit(T limit) {
74+
if (limit == lastLimit) return this->lastResults;
75+
std::vector<T> primes;
76+
if (limit < 2) return primes;
77+
primes.push_back(2);
78+
if (limit < 3) return primes;
79+
lastLimit = limit;
80+
auto sieve = create_sieve(limit);
81+
const size_t num_odds = ((limit - 3) >> 1) + 1;
82+
83+
for (size_t i = 0; i < num_odds; ++i)
84+
if (sieve[i >> 6] & (1ULL << (i & 63))) primes.emplace_back(3 + 2 * i);
85+
86+
lastResults = primes;
87+
return primes;
88+
}
89+
90+
bool is_prime(T n) {
91+
if (n <= 1) return false;
92+
if (n == 2) return true;
93+
if ((n & 1) == 0) return false;
94+
T sqrt_n = static_cast<T>(std::sqrt(n));
95+
auto sieve = from_range_limit(sqrt_n);
96+
for (T p : sieve)
97+
if (n % p == 0) return false;
98+
return true;
99+
}
100+
static int max_thread() { return Prime::maxThread; }
101+
};

discrete/src/fibonacci.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
#include <iostream>
2222
#include <cstring>
23-
#include "numbers.hxx"
23+
#include <fibonacci.hxx>
2424

2525
std::string argname[] = {"-h", "-help", "-l", "-limit", "-i", "-index"};
2626

discrete/src/prime.cxx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
#include <string>
2626
#include <vector>
2727

28-
#include "numbers.hxx"
28+
#include <prime.hxx>
2929

3030
uint64_t to_number_with_suffix(const char *str) {
3131
using namespace std;

0 commit comments

Comments
 (0)