-
Notifications
You must be signed in to change notification settings - Fork 0
/
no_evens.c
105 lines (81 loc) · 2.32 KB
/
no_evens.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#include <stdio.h>
#include <time.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>
#include "bitmap/bitmap.h"
bitmap_t bm;
/* 1 if num is prime, 0 otherwise. */
#define IS_PRIME(num) (!bitmap_is_bit_set(bm, NUM_TO_IND(num)))
#define NUM_TO_IND(num) ((num / 2) - 1)
/**
* mark_multiples - Mark all multiples of a prime number.
*
* This function goes through the bitmap, marking every multiple of a prime
* number as composite.
*
* prime: number to mark multiples of
* max: only mark multiples that are smaller than max
*/
static void mark_multiples(int prime, int max)
{
long long int primeLong = (long long int)prime;
long long int start = primeLong * primeLong;
if (start > max)
return;
for (int currNum = start; currNum < max; currNum += (prime * 2)) {
bitmap_set_bit(bm, NUM_TO_IND(currNum));
}
}
/**
* primes_up_to_no_evens - Compute primes up to a number.
*
* This function computes the primes of every integer up to a primeMax.
*
* primeMax: limit of numbers to sompute primeness
*
* Returns -1 if primesMax is not valid, the number of primes encountered
* otherwise.
*/
static int primes_up_to_no_evens(int primeMax)
{
/* We do not store evens, so we begin with one prime number, p=2. */
int numPrimes = 1;
if (primeMax < 2)
return -1;
int halfLimit = primeMax / 2;
/* Begin searching for prime numbers at p=3. */
int currNum = 3;
/* Iterate through odd numbers, checking if they are prime. */
for (; currNum < halfLimit; currNum += 2) {
/* Mark all multiples of a prime number. */
if (IS_PRIME(currNum)) {
mark_multiples(currNum, primeMax);
numPrimes++;
}
}
/* Search for any remaining primes between halfLimit and primeMax. */
for (; currNum < primeMax; currNum += 2) {
if (IS_PRIME(currNum))
numPrimes++;
}
return numPrimes;
}
int main(int argc, char **argv)
{
if (argc < 2) {
printf("Usage: ./<exec> prime_max\n");
return 1;
}
int primeMax = atoi(argv[1]);
/* Bitmap only stores odd numbers now. */
bm = bitmap_create(primeMax / 2);
clock_t startTime = clock();
int numPrimes = primes_up_to_no_evens(primeMax);
clock_t endTime = clock();
bitmap_destroy(bm);
double totalTime = endTime - startTime;
printf("There are %d prime numbers below %d.\n", numPrimes, primeMax);
printf("This program completed in %lf processor time units.\n", totalTime);
return 0;
}