Primality Testing — Part 3. A Further Optimized Method
The previous two posts cover the naive approaches for primality testing and a method with precomputation. This post introduces a new method which could perform better than previous approaches and it can be used together with the precomputation.
The optimization is based on the observation that all prime numbers are in the form of 6k+1 or 6k+5, with 2, 3 and 5 being the only exceptions. This is because all integers can be expressed in 6k+i for some integer k, and i is from the set {0, 1, 2, 3, 4, 5}. And 2 divides 6k+0, 6k+2 and 6k+4, 3 divides 6k+3.
Therefore, the primality test for a given integer n can be done by checking if n is divisible by 2 and 3 first, and then checking if n is divisible for all numbers of form 6k+1 or 6k+5 and less than sqrt(n).
The idea of this optimization is actually similar to the Sieve of Eratosthenes algorithm described in previous post. We eliminated testing divisibility for numbers that is divisible by the prime factors.
In general, all prime numbers are in the form gk + i, where i < k and it represents the numbers that are coprime to g. In the case above, g = 6 and the coprime of 6 are 1 and 5. If i and g are not coprime, then i must be divisible by some prime factors of g.
We go through another example, suppose g = 2*3*5 = 30, then all integers can be expressed in the form 30*k + i where i is in the set {0, 1, 2….29}. Now we mark the numbers that divisible by 2, 3 and 5 respectively. 30*k + {0, 2, 4, 6, 8, 10, 12, …28} are divisible by 2; 30*k + {3, 6, 9, 12, 15, 18, 21, 24, 27} are divisible by 3; and 30*k + {5, 10, 15, 20, 25} are divisible by 5. The rest of the numbers {1, 7, 11, 13, 17, 19, 23, 29} are not divisible by 2, 3 and 5 and are therefore coprimes of 30.
So to test if a number n is prime number, we first test if the number is divisible by 2, 3, and 5 first, and then check if the number is divisible by numbers in the form 30*k + {1, 7, 11, 13, 17, 19, 23, 29} up to sqrt(n).
Below is an implementation of the optimization for primality testing when g is set to 6,
/**
generate prime numbers
**/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int rdiv(int n, int m) {
if (n%m ==0) {
printf("%d is divisible by %d\n", n, m);
return 0;
}
return 1;
}
int prime(int n) {
int i, k, ed, m;
int cpr[2] = {1, 5};
//check if we can divide the prime factors first
if (n == 2 || n == 3) {return 1;}
if (rdiv(n, 2) == 0) {
return 0;
} else if (rdiv(n, 3) == 0) {
return 0;
}
//printf("ifprime: %d", ifprime);
//check up to sqrt(n) of the form 6k + {coprime of 6}
ed = sqrt(n) + 1;
for (k = 0; ;++k) {
for (i = 0; i < 2; ++i) {
m = 6*k + cpr[i];
if (m < 3) {continue;}
if (m > ed) {
return 1;
}
if (n%m == 0) {
printf("%d is divisible by %d\n", n, m);
return 0;
}
}
}
return 1;
}
int main(int argc, char **argv) {
int n = atoi(argv[1]);
int i;
struct timeval stTime, edTime;
gettimeofday(&stTime, NULL);
if (prime(n)) {
printf("%d is prime number\n", n);
} else {
printf("%d is not prime number\n", n);
}
gettimeofday(&edTime, NULL);
printf("time: %u:%u\n", (unsigned int)(edTime.tv_sec - stTime.tv_sec), (unsigned int)(edTime.tv_usec - stTime.tv_usec));
return 0;
}
Save the code to prim4.c and compile the code with command below,
gcc -o prim4 prim4.c –lm
Below are some simple tests:
roman10@ra-ubuntu-1:~/Desktop/integer/prim$ ./prim4 2
2 is prime number
time: 0:49
roman10@ra-ubuntu-1:~/Desktop/integer/prim$ ./prim4 3
3 is prime number
time: 0:62
roman10@ra-ubuntu-1:~/Desktop/integer/prim$ ./prim4 5
5 is prime number
time: 0:52
roman10@ra-ubuntu-1:~/Desktop/integer/prim$ ./prim4 2147483647
2147483647 is prime number
time: 0:267
roman10@ra-ubuntu-1:~/Desktop/integer/prim$ ./prim4 2147483641
2147483641 is divisible by 2699
2147483641 is not prime number
time: 0:72
Note that the code can be further improved by adding the pre-computation we mentioned in part2.
Leave a Reply Cancel reply
40% Discount on My Book — Android NDK Cookbook
Android NDK Cookbook ebook 40% discount with promotion code MREANC40 at Packt Publishing The promotion code is valid until 15th June.Categories
- Android Apps (18)
- Android Audio Editor (1)
- TS 2 (3)
- Video Converter Android (8)
- Video2Gif (1)
- Android Tutorial (26)
- Android Dev Tools (1)
- API illustrated (8)
- Multimedia API (3)
- ffmpeg on Android (4)
- NDK (6)
- UI (5)
- Animation (1)
- Code Snippet (2)
- Coding Beyond Technique (18)
- a word, a world (4)
- Bug Rectified (4)
- Programming Habit (1)
- Software as a Career (1)
- Software as User Experience (1)
- Compilers and Related (2)
- ELF (2)
- Computer Languages (31)
- C/C++ (13)
- Java (9)
- JavaScript (2)
- PHP (1)
- Python (8)
- Data Structure & Algorithms (29)
- Bits (1)
- Data Structure (5)
- Integers (10)
- BigInteger (1)
- Prime (4)
- Search (3)
- Sorting (5)
- Strings (5)
- Database (1)
- SQLite (1)
- Digital Signal Processing (33)
- Distributed Systems (17)
- Apache Cassandra (6)
- Apache Hadoop (8)
- Apache Avro (3)
- Apache Nutch (3)
- Apache Solr (1)
- Linux Study Notes (40)
- crontab (1)
- Linux Kernel Programming (8)
- Linux Programming (12)
- IPC (2)
- Linux Network Programming (5)
- Linux Signals (2)
- Linux Shell Scripting (1)
- ssh (3)
- Machinery (30)
- misc (1)
- My Ideas (1)
- My Project (3)
- Mobile Caching (1)
- Selective Decoding (2)
- My Publication (1)
- My Readings (1)
- Networking (15)
- Program for Performance (8)
- Uncategorized (1)
- Virtual Machine (2)
- Web Dev (8)
- web components (3)
- Android Apps (18)
Recent Comments
Archives
- May 2013 (1)
- April 2013 (1)
- March 2013 (4)
- December 2012 (2)
- November 2012 (6)
- October 2012 (6)
- September 2012 (3)
- August 2012 (13)
- July 2012 (15)
- June 2012 (3)
- May 2012 (8)
- April 2012 (4)
- March 2012 (13)
- February 2012 (19)
- January 2012 (9)
- December 2011 (11)
- November 2011 (12)
- October 2011 (4)
- September 2011 (12)
- August 2011 (16)
- July 2011 (15)
- June 2011 (6)
- May 2011 (10)
- April 2011 (13)
- March 2011 (20)
- February 2011 (4)
- November 2010 (2)
- May 2010 (1)
- April 2010 (1)
- February 2010 (1)




