-
Notifications
You must be signed in to change notification settings - Fork 30
/
Copy pathprime.c
81 lines (72 loc) · 2.13 KB
/
prime.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
/**
* @file prime.c
* @author hutusi ([email protected])
* @brief Refer to prime.h
* @date 2019-07-21
*
* @copyright Copyright (c) 2019, hutusi.com
*
*/
#include "prime.h"
#include "def.h"
#include <math.h>
static inline unsigned int bit_map_index_to_number(unsigned int n)
{
/** from 3: [0] => 3, [1] => 5 */
return n * 2 + 3;
}
/** para number must be odd number */
static inline unsigned int bit_map_number_to_index(unsigned int number)
{
/** from 3: [0] => 3, [1] => 5 */
return (number - 3) / 2;
}
BitMap *prime_number_sieve(unsigned int max_number)
{
/** prime number should be odd number (except 2),
* so we only need sieve half of the number.
* 1 is no need to sieve either.
*/
unsigned int sieve_size = (max_number - 1) / 2;
BitMap *sieve = bitmap_new(sieve_size);
bitmap_set_all(sieve);
/** only need loop to sqrt(max_number) */
double max_sqrt = sqrt((double)max_number);
int max_loop = (unsigned int)ceil(max_sqrt) / 2 + 1;
for (unsigned int i = 0; i < max_loop; ++i) {
/** no need to sieve composite's multiples */
if (!bitmap_get(sieve, i))
continue;
unsigned int base_prime = bit_map_index_to_number(i);
/** each time start from base_prime * base_prime, sieve 3 * 3 first,
* etc. */
unsigned int composite = base_prime * base_prime;
while (composite <= max_number) {
/** sieve prime */
unsigned int index = bit_map_number_to_index(composite);
bitmap_clear(sieve, index);
composite += (base_prime + base_prime); /** skip even number */
}
}
return sieve;
}
int prime_number_sieve_check(const BitMap *sieve, unsigned int number)
{
if (number < 2) {
return 0;
} else if (number == 2) {
return 1;
} else if (number % 2 == 0) {
return 0;
} else {
return bitmap_get(sieve, bit_map_number_to_index(number));
}
}
unsigned int prime_number_sieve_count(const BitMap *sieve)
{
return bitmap_count(sieve) + 1; /** plus prime 2 */
}
void prime_number_sieve_free(BitMap *sieve)
{
bitmap_free(sieve);
}