- If you aren't using a sieve, why did you have a sieve generator in the partial code that you posted?
- You said that your code was (apparently) working and you asked for suggestions to speed it up for that particular problem. How big is an array of one million and one booleans? That's the sieve size for your problem, right? I mean, a million booleans isn't much of a strain on any kind of workstation people are using these days, right?
- If you want to get meaningful help in the fewest number of iterations, why would you not show us (in your original post) the part that is most likely to be the bottleneck?
- The function in your most recent post has an int parameter. The code that you posted previously used longs. I think that getting help in the fewest number of iterations usually would require that you give us exactly what you are working on. I mean, I always test things before I offer suggestions. How the heck can I know what gives improved performance since I don't know what you are using?
Oh, well...
If you want a faster prime number tester that will work for all positive 32-bit integer values and doesn't involve a Sieve: Here's something that can be used with your circular prime program (after changing main() function variables to ints), and finds all of the circular primes less than a million in something like 1500 milliseconds on my machine (compared to something over 15 minutes with your brute-force isPrime and compared to roughly 150 milliseconds with a Sieve).
static boolean isPrime(int n)
{
if (n <= 1) return false;
if (n == 2) return true;
if (n % 2 == 0) return false;
if (n < 9) return true;
if (n % 3 == 0) return false;
if (n % 5 == 0) return false;
// mods[] = {2, 3} gives no false positives for numbers < 1,373,653
// {31, 73} gives no false positives for numbers < 9,080,191
//int mods[] = {2, 3};
//int mods[] = {31, 73};
// {2,7,61} gives no false positives for numbers < 4,759,123,141
// However it will give negative for 2, 7, and 61. 2 and
// 7 have already been taken care of.
int mods[] = {2, 7, 61};
if (n == 61)
{
return true;
}
for (int i = 0; i < mods.length; i++)
{
if (Witness(mods[i], n)) return false;
}
return true;
}
static boolean Witness(int a, long n)
{
long t = 0;
long u = n - 1;
while ((u & 1) == 0) {
t++;
u >>>= 1;
}
long xi1 = ModularExp(a, u, n);
long xi2;
for (long i = 0; i < t; i++)
{
xi2 = (xi1 * xi1) % n;
if ((xi2 == 1) && (xi1 != 1) && (xi1 != (n - 1))) return true;
xi1 = xi2;
}
if (xi1 != 1) return true;
return false;
}
// Calculates (a**b) modulo n
static long ModularExp(int a, long b, long n)
{
long d = 1;
int k = 0;
while ((b >>> k) > 0) k++;
for (int i = k - 1; i >= 0; i--) {
d = (d * d) % n;
if (((b >>> i) & 1) > 0) d = (d * a) % n;
}
return d;
}
It starts with "Fermat's little theorem" and goes through a couple of rounds to eliminate false positives (pseudo-primes) for numbers over the entire range of (positive) 32-bit signed integers (and a little more).
Why did I delete almost all of the comments from my prime number code? If people are interested in the theory, they can look up the procedure (I think I gave enough key words for a search engine). If they aren't interested in the theory, and if they only want something that works (or so I claim), well they wouldn't read the comments anyhow.
Cheers,
Z