费马定理的逆定理几乎可以用来判断一个数是否为素数,但是有一些数是判断不出来的,因此,Miller_Rabin测试方法对费马的测试过程做了改进,克服其存在的问题。

推理过程如下(摘自维基百科):

摘自另一篇博文(手动滑稽):

原理明白了,就直接上代码了(KuangBin大神的板子):

代码思路是,

  • Miller_Rabin()函数随机选取 s 个a,a用做“基底”
  • check() 函数是用来判断x是否等于1,也就是判断a是否是n的凭证。
  • Mul_mod()函数是 快速乘 ,求 a^t % n 之后的值是否为正负一,因为两个数直接乘的话会很大,可能会爆Long Long, 因此用快速乘边乘边mod。
  • pow_mod()函数是 快速幂 ,在刚开始第一次判断 a^(n-1) % n 时会用到。
 /* *************************************************
* Miller_Rabin 算法进行素数测试
* 速度快可以判断一个 < 2^63 的数是不是素数
*
**************************************************/
const int S = ; //随机算法判定次数一般 8 ∼ 10 就够了
// 计算 ret = (a*b)%c
//a,b,c < 2^63
long long mult_mod(long long a,long long b,long long c)
{
a %= c;
b %= c;
long long ret = ;
long long tmp = a;
while(b)
{
if(b & )
{
ret += tmp;
if(ret > c)ret -= c;//直接取模慢很多
}
tmp <<= ;
if(tmp > c)tmp -= c;
b >>= ;
}
return ret;
}
// 计算 ret = (a^n)%mod
long long pow_mod(long long a,long long n,long long mod)
{
long long ret = ;
long long temp = a%mod;
while(n)
{
if(n & )ret = mult_mod(ret,temp,mod);
temp = mult_mod(temp,temp,mod);
n >>= ;
}
return ret;
}
// 通过 a^(n − 1)=1(mod n)来判断 n 是不是素数
// n − 1 = x ∗ 2 t 中间使用二次判断
// 是合数返回 true, 不一定是合数返回 false
bool check(long long a,long long n,long long x,long long t)
{
long long ret = pow_mod(a,x,n);
long long last = ret;
for(int i = ; i <= t; i++)
{
ret = mult_mod(ret,ret,n);
if(ret == && last != && last != n - )return true;//合数
last = ret;
}
if(ret != )return true;
else return false;
}
//**************************************************
// Miller_Rabin 算法
// 是素数返回 true,(可能是伪素数)
// 不是素数返回 false
//**************************************************
bool Miller_Rabin(long long n)
{
if( n < )return false;
if( n == )return true;
if( (n&) == )return false;//偶数
long long x = n - ;
long long t = ;
while( (x&)== )
{
x >>= ;
t++;
}
srand(time(NULL));/* *************** */
for(int i = ; i < S; i++)
{
long long a = rand()%(n - ) + ;
if( check(a,n,x,t) )
return false;
}
return true;
}

最新文章

  1. iframe框架用法
  2. Codeforces Round #381(div 2)
  3. C#中对string与string[]的初步操作
  4. what we do and how we behave
  5. 【QT】C++ GUI Qt4 学习笔记4
  6. Keepalived+tomcat的HA配置
  7. 怎样在VS2010中打开VS2012的项目
  8. [hive小技巧]同一份数据多种处理
  9. SVG 动画实现弹性的页面元素效果
  10. SaundProgressBar
  11. linux学习书籍推荐linux学习书籍推荐
  12. Android更改imagebutton为纯色方法
  13. itoo-快捷部署脚本--提高部署开发效率
  14. VScode查找替换常用正则表达式
  15. vs code 快捷键中英文对照
  16. 普通java程序,maven打包
  17. 【Java集合的详细研究4】Java中如何遍历Map对象的4种方法
  18. 【scrapy】使用方法概要(一)(转)
  19. 基于FPGA的5寸LCD显示屏的显示控制
  20. 插入排序 思想 JAVA实现

热门文章

  1. arduino按钮使用的两个小实验
  2. pandas读取csv数据时设置index
  3. Citrix Merchandising Server 配置
  4. hao360恶意篡改IE首页——修复方法
  5. Django如何安装指定版本
  6. MyBatis传入多个参数的问题(转)
  7. 怎么把焦点放在RichEdit的最后一行
  8. 跨语言通信方案的比较—Thrift、Protobuf和Avro
  9. Python中xlrd和xlwt模块读写Excel的方法
  10. AJAX 原生态