Java中的Miller-Rabin Primality测试

时间:2013-06-13 06:35:35

标签: java primes number-theory

我目前正致力于Project Euler并认为如果不是强行提出所有问题,那可能会更有趣(以及更好的学习经历)。在问题3,它询问数字的素因子,我的解决方案是计算数字(使用另一个因子算法),然后测试素数因子。我想出了这个代码用于Miller-Rabin Primality测试(在彻底研究素性测试之后),并且它对于我放入的所有复合奇数都返回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;
}

1 个答案:

答案 0 :(得分:4)

给定num > 3,您需要:d, r s.t. pow(2,r) * d = num - 1, where d is odd

您实际上正在计算来自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 测试)进行测试的循环对我来说是完全错误的。

也许你有Wikipedia的算法,我更喜欢The Handbook of Applied Cryptography中更详细的参考: 4.2.3:Miller-Rabin测试,算法:4.24