patternjavaMinor
Fermat primality test
Viewed 0 times
fermattestprimality
Problem
Here is a simple working Java implementation of primality test for Fermat numbers. Is there something that I could change in code to achieve a better running time?
import java.math.BigInteger;
public class FPT
{
public static void main(String[] args)
{
double n;
n = Double.parseDouble(args[0]);
int e = (int)n;
if (e > 1)
{
double m = Math.pow(2,n);
int k = (int)m;
BigInteger F;
F = BigInteger.valueOf(2).pow(k).add(BigInteger.ONE);
BigInteger s = new BigInteger ("8");
double o = 1;
double a = n - o ;
double b = Math.pow(2,a) - o;
int c = (int)b;
for (int i = 1; i <= c; i ++)
{
s=s.pow(4).subtract(BigInteger.valueOf(4).multiply(s.pow(2))).add(BigInteger.valueOf(2)).mod(F);
}
if (s.equals(BigInteger.ZERO))
{
System.out.println("prime");
}
else
{
System.out.println("composite");
}
}
else
{
System.out.println("exponent must be greater than one");
}
}
}Solution
I still can't quite figure out the way to this algorithm =/. But, from the Java point of view, you can gain 9-10% by changing your loop to:
...because the cached value can be used twice there.
Otherwise, the code is hard to read. It's not self explanatory nor commented and could be written in a better way - for a human to read, at least. But none of those changes would affect performance in any way.
EDIT: Additional 17% thanks to @Landei in comments.
That takes advantage of
for (int i = 1; i <= c; i ++) {
BigInteger temp = s.pow(2);
s = temp.pow(2).subtract(BigInteger.valueOf(4).multiply(temp)).add(BigInteger.valueOf(2)).mod(F);
}...because the cached value can be used twice there.
Otherwise, the code is hard to read. It's not self explanatory nor commented and could be written in a better way - for a human to read, at least. But none of those changes would affect performance in any way.
EDIT: Additional 17% thanks to @Landei in comments.
for (int i = 1; i <= c; i ++) {
BigInteger temp = s.modPow(BigInteger.valueOf(2), F);
s = temp.pow(2).subtract(BigInteger.valueOf(4).multiply(temp)).add(BigInteger.valueOf(2));
}
s = s.mod(F);That takes advantage of
modPow() method which can do pow().mod() in one step without much additional overhead. Since the mod is not necessary to have every time, it is enough to do it in temp (that actually propagates twice into the resulting expression) and enjoy the substantial speedup. You need to add one proper mod after the loop is done, though.Code Snippets
for (int i = 1; i <= c; i ++) {
BigInteger temp = s.pow(2);
s = temp.pow(2).subtract(BigInteger.valueOf(4).multiply(temp)).add(BigInteger.valueOf(2)).mod(F);
}for (int i = 1; i <= c; i ++) {
BigInteger temp = s.modPow(BigInteger.valueOf(2), F);
s = temp.pow(2).subtract(BigInteger.valueOf(4).multiply(temp)).add(BigInteger.valueOf(2));
}
s = s.mod(F);Context
StackExchange Code Review Q#10560, answer score: 4
Revisions (0)
No revisions yet.