【发布时间】:2013-06-09 11:02:59
【问题描述】:
我目前正在研究Project Euler,并认为如果不只是蛮力解决所有问题,它可能会更有趣(以及更好的学习体验)。在问题 3 中,它要求一个数的素因数,我的解决方案是对数进行因式分解(使用另一种因式分解算法),然后测试这些因数的素数。我为米勒-拉宾素性测试提出了这段代码(在彻底研究素性测试之后),它对我输入的所有复合奇数返回 true。有人能帮我找出原因吗?我以为我已经正确编码了算法。
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;
}
【问题讨论】:
-
你试过追踪代码吗?
-
这与您的代码无关,我也没有多少专业知识,但是“分解数字(使用另一种分解算法)”是一个比识别素数更难的问题。您可以通过获取素数列表来避免强制分解。获取素数列表(与测试素数相对应)的最简单方法是使用筛子。
-
@JanDvorak:提出了一个很好的观点。您应该考虑用 BigInteger 类替换 long 的使用。
-
@JuanSebastianLozanoMuñoz:22?这听起来很奇怪。我希望第一个 if 条件能够捕捉到这一点。你确定你调用的是正确的函数吗?
-
不应该
while(num % Math.pow(2,r+1) == 0)是while((num-1) % Math.pow(2,r+1) == 0)或者更好(对我来说)while((num-1) % (1<<r+1) == 0)然后是d = ((num-1) % (1<<r));
标签: java primes number-theory