找回密码
 欢迎注册
查看: 7277|回复: 6

[提问] Miller-Rabin测试怪现象??

[复制链接]
发表于 2010-5-4 15:25:34 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?欢迎注册

×
不知是我写错了,还是本来如此,发现65537居然不能通过以3为底的测试。
请教!
我的java代码如下:
boolean IsPrime(int N){
        int[] primes =new int[]{2,3,5,7,11}; /底,据说2^32以内的数用这5个底就可以了
                if(N<13){
                        if(N==2 || N==3 || N==5 || N==7 || N==11){
                                return true;
                        }else{
                                return false;
                        }
                }
                if(N % 2==0)return false;//不加这句的话,下面紧接着的循环会出错
                int m=N-1;int j=0;               
                while(m % 2==0){ ;//此循环计算(2^j)*m=N-1;
                        m/=2;
                        j++;
                }
                for(int i=0;i<5;i++){
                        int v=PowMod(primes[i],m,N);//模幂算法
                        ;//v=1,可能是素数,跳过
                        if(v!=1){;//v不等于1,可能不是素数。
                                int k=1;
                                while(v!=N-1){
                                        if(k==j)return false;//一定不是素数,返回false
                                        k++;
                                        v*=v;
                                        v%=N;
                                }
                                ;//运行到这里,说明v=N-1,可能是素数,跳过
                        }
                        ;//运行到这里,说明第i次测试可能是素数
                }
                        ;//运行到这里,说明在2^32内一定是素数
                return true;
        }
后来,我把代码改成了这样,就通过了:
boolean IsPrime(int N){
        int[] primes =new int[]{2,3,5,7,11};
                if(N<13){
                        if(N==2 || N==3 || N==5 || N==7 || N==11){
                                return true;
                        }else{
                                return false;
                        }
                }
                for(int i=0;i<5;i++){
                        int v=PowMod(primes[i],N-1,N);
                        if(v!=1 && v!=N-1){
                                return false;
                        }
                }
                return true;
        }

请问为什么?
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-5-4 15:39:53 | 显示全部楼层
素数怎么可能通不过,肯定是你程序问题了,你下载个RSA1.0的对照一下就知道错在哪了
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-5-4 15:49:45 | 显示全部楼层
你的代码中含有“v*=v;”,
请检查一下是否有溢出之可能,
比如当 v=65536 时,v*=v 结果会是什么?(32位int型)
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-5-4 16:24:35 | 显示全部楼层
int v=PowMod(primes[i],m,N);//模幂算法

  int v=PowMod(primes[i],N-1,N);
这里的m跟N-1值是完全不同,在上式中m的值是1,在下式中m的值是65536
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-5-4 22:16:47 | 显示全部楼层
可能是v*v溢出了,谢谢3楼!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
 楼主| 发表于 2010-5-4 22:24:16 | 显示全部楼层
谢谢,刚刚把int v改成long v,果然没问题了!谢谢gxqcn!
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
发表于 2010-5-5 07:50:24 | 显示全部楼层
防止“溢出”,不仅仅是加减法,还有乘法等,
此类错误,编译器不会给你任何警告,
但开发者必须做到心中有数,避免数据出现意料外的“回绕”。
毋因群疑而阻独见  毋任己意而废人言
毋私小惠而伤大体  毋借公论以快私情
您需要登录后才可以回帖 登录 | 欢迎注册

本版积分规则

小黑屋|手机版|数学研发网 ( 苏ICP备07505100号 )

GMT+8, 2024-4-28 10:11 , Processed in 1.783162 second(s), 16 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表