Solovary-Strassen 计算幂次模n值 改进 位运算

来源:互联网 发布:淘宝差评怎么写才过瘾 编辑:程序博客网 时间:2024/06/04 00:54

Solovary-Strassen

#include<stdio.h>#include<iostream>#include<stdlib.h>#include<time.h>using namespace std;#define MAX_TIME 11111#define DATA_TYPE long longbool Solovay_Strassen(DATA_TYPE n, int t);int Jacobi(DATA_TYPE a,DATA_TYPE n);DATA_TYPE ComputeR(DATA_TYPE a,DATA_TYPE k,DATA_TYPE n);//计算r=a^k mod nint main(){    DATA_TYPE n;    clock_t start_time,end_time;    while(1){        start_time = clock();        cout << "计算开始时间:" << start_time << endl;        cout << "请输入要判断的数:";        cin >> n;        if(n<=1 || (n>2 && n%2==0)||!Solovay_Strassen(n,n>MAX_TIME?MAX_TIME:n-2))            cout << n << "不是素数" << endl;        else            cout << n << "是素数" << endl;        end_time = clock();        cout << "OK!计算完成,运行时间为" << end_time-start_time << "毫秒" << endl;        cout << endl;    }    return 0;}bool Solovay_Strassen(DATA_TYPE n, int t){    int i;    DATA_TYPE Rand_Num,r,jac;    srand((unsigned int)time(NULL));    for(i = 0; i < t; i++){        //判断是否有随机数重复,如重复则重新生成,在n足够大时,这一段理论上可忽略        DATA_TYPE Choosed[MAX_TIME]; //记录已选择的随机数        bool flag;  //标记是否有重复值        do{            flag =0;            do{                Rand_Num = rand()%n;            }while(Rand_Num < 1 || Rand_Num > n-1);            for(int j=0; j < i; j++){                if(Rand_Num == Choosed[j]){ //已选择过                    flag = 1;   //置标记位为1                    break;                }            }        }while(flag);        Choosed[i] = Rand_Num;        do{            Rand_Num=rand()%n;        }while(Rand_Num <= 1 || Rand_Num > n-1);        r = ComputeR(Rand_Num,(n-1)/2,n);        if(!(1 == r || r == n-1))            return 0;        jac = Jacobi(Rand_Num,n);        if(jac < 0)            jac = n + jac;        if(r != jac)            return 0;        }    return 1;}int Jacobi(DATA_TYPE a,DATA_TYPE n){    DATA_TYPE temp,e = 0, a1, n1;    int s;    if(0 == a || 1 == a)        return 1;    temp = a;    while(temp % 2 == 0){        temp /= 2;        e++;    }    a1 = temp;    if(0 == e % 2)        s = 1;    else{        if(1 == n%8 || 7 == n%8)            s = 1;        else if(3 == n%8 || 5 == n%8)            s = -1;    }    if(3 == n%4 && 3 == a1%4)        s = -s;    n1 = n % a1;    if(1 == a1)        return s;    else        return s * Jacobi(n1,a1);}int quick(DATA_TYPE a,DATA_TYPE b,DATA_TYPE c){    DATA_TYPE ans=1;   //记录结果    a=a%c;   //预处理,使得a处于c的数据范围之下    while(b!=0)    {        if(b&1) ans=(ans*a)%c;   //如果b的二进制位不是0,那么我们的结果是要参与运算的        b>>=1;    //二进制的移位操作,相当于每次除以2,用二进制看,就是我们不断的遍历b的二进制位        a=(a*a)%c;   //不断的加倍    }    return ans;}DATA_TYPE ComputeR(DATA_TYPE a,DATA_TYPE k,DATA_TYPE n){    return quick(a,k,n);}


原创粉丝点击