zoukankan      html  css  js  c++  java
  • Miller_Rabin 素数测试

    费马定理的逆定理几乎可以用来判断一个数是否为素数,但是有一些数是判断不出来的,因此,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 时会用到。 
     1 /* *************************************************
     2 * Miller_Rabin 算法进行素数测试
     3 * 速度快可以判断一个 < 2^63 的数是不是素数
     4 *
     5 **************************************************/
     6 const int S = 8; //随机算法判定次数一般 8 ∼ 10 就够了
     7 // 计算 ret = (a*b)%c
     8 //a,b,c < 2^63
     9 long long mult_mod(long long a,long long b,long long c)
    10 {
    11     a %= c;
    12     b %= c;
    13     long long ret = 0;
    14     long long tmp = a;
    15     while(b)
    16     {
    17         if(b & 1)
    18         {
    19             ret += tmp;
    20             if(ret > c)ret -= c;//直接取模慢很多
    21         }
    22         tmp <<= 1;
    23         if(tmp > c)tmp -= c;
    24         b >>= 1;
    25     }
    26     return ret;
    27 }
    28 // 计算 ret = (a^n)%mod
    29 long long pow_mod(long long a,long long n,long long mod)
    30 {
    31     long long ret = 1;
    32     long long temp = a%mod;
    33     while(n)
    34     {
    35         if(n & 1)ret = mult_mod(ret,temp,mod);
    36         temp = mult_mod(temp,temp,mod);
    37         n >>= 1;
    38     }
    39     return ret;
    40 }
    41 // 通过 a^(n − 1)=1(mod n)来判断 n 是不是素数
    42 // n − 1 = x ∗ 2 t 中间使用二次判断
    43 // 是合数返回 true, 不一定是合数返回 false
    44 bool check(long long a,long long n,long long x,long long t)
    45 {
    46     long long ret = pow_mod(a,x,n);
    47     long long last = ret;
    48     for(int i = 1; i <= t; i++)
    49     {
    50         ret = mult_mod(ret,ret,n);
    51         if(ret == 1 && last != 1 && last != n - 1)return true;//合数
    52         last = ret;
    53     }
    54     if(ret != 1)return true;
    55     else return false;
    56 }
    57 //**************************************************
    58 // Miller_Rabin 算法
    59 // 是素数返回 true,(可能是伪素数)
    60 // 不是素数返回 false
    61 //**************************************************
    62 bool Miller_Rabin(long long n)
    63 {
    64     if( n < 2)return false;
    65     if( n == 2)return true;
    66     if( (n&1) == 0)return false;//偶数
    67     long long x = n - 1;
    68     long long t = 0;
    69     while( (x&1)==0 )
    70     {
    71         x >>= 1;
    72         t++;
    73     }
    74     srand(time(NULL));/* *************** */
    75     for(int i = 0; i < S; i++)
    76     {
    77         long long a = rand()%(n - 1) + 1;
    78         if( check(a,n,x,t) )
    79             return false;
    80     }
    81     return true;
    82 }
    View Code
  • 相关阅读:
    Hive函数大全
    SparkSQL与Hive on Spark
    Hadoop安装—— WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platf
    centos7配置防火墙
    hive使用
    SPOOL 命令使用实例【oracle导出纯文本格式文件】
    IP 跟踪
    chinaunix---linux教程
    Python语言获取目录下所有文件
    m
  • 原文地址:https://www.cnblogs.com/daybreaking/p/9853433.html
Copyright © 2011-2022 走看看