我正在编写一个程序来演示Java中的Miller-Rabin概率测试。代码已经完成了......
import java.util.Random;
import java.util.Scanner;
/**
* Program to demonstrate Miller-Rabin primality testing
*
* @author Nick Gilbert
*/
public class MillerRabin
{
public static void main(String[] args)
{
//Setting up for algorithm
Scanner in = new Scanner(System.in);
Random rn = new Random();
int n = 0, k = 0, m = 0, a = 0;
double b = 0;
boolean probablyPrime = false;
//Asking user for an odd n
do
{
System.out.print("Enter an odd number to test for primality: ");
n = in.nextInt();
}
while(n % 2 == 0);
//Calculating k and m
m = n - 1;
while(m % 2 == 0)
{
m /= 2;
k++;
}
//Generating random a
//a = rn.nextInt(n-1);
//Outputting numbers that will be used in algorithm
System.out.println("k = " + k);
System.out.println("m = " + m);
System.out.println();
a = 86;
System.out.println("A = " + a);
//Running the algorithm
//b_{0}
b = Math.pow(a, m) % n;
System.out.println("b0 = " + b);
if(Math.abs(b) == Math.abs(1 % n)) //Dealing with +/- case via absolute value
{
probablyPrime = true;
}
else
{
//b_{1-(k-1)}
for(int i = 1; i < k; i++) //Going to k-1
{
b = Math.pow(b, 2) % n;
System.out.println("b" + i + " = " + b);
if(Math.abs(b) == Math.abs(1 % n)) //Dealing with +/- case via absolute value
{
probablyPrime = true;
break;
}
}
}
//Printing result
if(probablyPrime)
{
System.out.println("Probably Prime");
}
else
{
System.out.println("Definitely Composite");
}
}
}
我已经硬编码86作为我的价值来证明我的问题。在第一次通过将a提高到m并且取模数n来计算b时,数学是不正确的。而不是给出86的b0是86 ^ 19%153的正确答案,它给了我b0等于107.我在调试器中检查了我的值,它们是正确的。我还检查了a ^ m的值,它给了我86 ^ 19所以模数部分出现问题。不幸的是,我不知道是什么让数学失败了。
答案 0 :(得分:2)
double
精度只有15-16位精度。如果使用大于此数字的数字,则会出现表示错误。
你最需要做的就是使用BigInteger,它不仅可以处理任意精度,而且还有针对电源和电源优化的方法。模量
// 86^19 % 153
BigInteger result = BigInteger.valueOf(86).modPow(BigInteger.valueOf(19), BigInteger.valueOf(153));
System.out.println(result);
打印
86
答案 1 :(得分:1)
Here,Math.pow返回一个double,所以取一个double的模数无济于事(永远不要把一个Mod加倍,没有人对你得到的东西负责)。
并注意,(89 ^ 19)大约是2 ^ 122,因此无符号长(2 ^ 64-1)不会保留这些数字。和double有一个精度2 ^ 53(从不使用double to mod,数论是整数)。尝试使用较小的值或使用BigInteger类。
答案 2 :(得分:0)
primitive data types设置的尺寸会限制其准确性。
Java有BigInteger类,可以适用于您的场景。