Java中的Miller-Rabin素性测试
我目前正在研究,并认为如果不只是强行解决所有问题,可能会更有趣(和更好的学习体验)。在问题3中,它要求求一个数的素数因子,我的解决方案是对该数进行因子分解(使用另一种因子分解算法),然后测试素数因子。我为Miller-Rabin素性测试(在彻底研究了素性测试之后)编写了这段代码,对于我输入的所有复合奇数,它返回true。有人能帮我弄清楚原因吗?我以为我把算法编对了Java中的Miller-Rabin素性测试,java,primes,number-theory,Java,Primes,Number Theory,我目前正在研究,并认为如果不只是强行解决所有问题,可能会更有趣(和更好的学习体验)。在问题3中,它要求求一个数的素数因子,我的解决方案是对该数进行因子分解(使用另一种因子分解算法),然后测试素数因子。我为Miller-Rabin素性测试(在彻底研究了素性测试之后)编写了这段代码,对于我输入的所有复合奇数,它返回true。有人能帮我弄清楚原因吗?我以为我把算法编对了 public static boolean isPrime(long num) { if(num % 2 == 0)
public static boolean isPrime(long num)
{
if(num % 2 == 0)
return false;
else
{
double d;
int r=0;
while((num-1) % Math.pow(2,r+1) == 0)
r++;
d = (num-1) % Math.pow(2,r);
int[] a = {2,3,5,7,11,13,17,23,31,62,73,1662803};
boolean primality = true;
for(int k = 0; k < a.length; k++)
{
if((Math.pow(a[k],d)-1) % num != 0)
{
for(int s = 0; s < r-1; s++)
{
if((Math.pow(a[k],Math.pow(2,s)*d)+1) % num != 0)
primality = false;
}
}
}
return primality;
}
public静态布尔值isPrime(long num)
{
如果(数值%2==0)
返回false;
其他的
{
双d;
int r=0;
而((num-1)%Math.pow(2,r+1)==0)
r++;
d=(num-1)%Math.pow(2,r);
int[]a={2,3,5,7,11,13,17,23,31,62,731662803};
布尔素性=真;
for(int k=0;k
给定num>3
,您需要:d,rst.pow(2,r)*d=num-1,其中d为奇数
您正在有效地从num-1
中计算尾随零,以去除2
的因子。但是,在该循环之后,您知道pow(2,r)
是num-1
的因子。因此:
d = (num-1) % Math.pow(2,r);
将始终产生:d=0
。我怀疑您打算在这里用/
(div)替换%
(mod);否则,Math.pow(a[k],d)-1将始终产生(0)
,并且内部循环将永远不会执行
正如其他人指出的,一些简单的跟踪语句或断言可能会发现这些错误。我认为您还存在其他问题,例如整数溢出。针对a[]
候选项(a-SPRP测试)进行测试的循环在我看来是完全错误的
也许你从中得到了算法,我更喜欢更详细的参考:4.2.3:Miller-Rabin测试,算法:4.24你试过跟踪代码吗?这与你的代码无关,我也不要求太多专业知识,但“分解数字(使用另一种分解算法)”这是一个比识别素数更难的问题。你可以通过获取素数列表来避免强行进行因式分解。获取素数列表的最简单方法(与测试素数列表类似)是使用筛子。@JanDvorak:这一点很重要。你应该研究用类替换long的用法。@JuanSebastianLozanoMuñoz:22?这听起来很奇怪。我希望第一个if条件能抓住这个问题。你确定你调用了正确的函数吗?不应该while(num%Math.pow(2,r+1)==0)
bewhile((num-1)%Math.pow(2,r+1)==0)
或者更好(在我看来),而((num-1)%(1感谢您提供了这个非常有用的答案:)我将研究您提供的资源,因为它们似乎非常有用,下次将更加小心地使用跟踪语句(现在我知道它们是什么)@JuanSebastianLozanoMuñoz-既然你正在处理Euler项目的问题,我想你可能会发现一个高效的Miller-Rabin测试很有用,所以我有一个片段给你。哇,非常感谢:)这肯定会帮助我解决PE问题。