位运算模拟乘法,模指数运算

1. 整数乘法(位运算)

使用位运算模拟乘法,其遵照以下的数学原理,即:
a b = a ( b 0 2 0 + b 1 2 1 + ⋅ ⋅ ⋅ + b n − 1 2 n − 1 ) = a ( b 0 2 0 ) + a ( b 1 2 1 ) + ⋅ ⋅ ⋅ + a ( b n − 1 2 n − 1 ) ab=a(b_02^0+b_12^1+···+b_{n-1}2^{n-1}) \\ \quad=a(b_02^0)+a(b_12^1)+···+a(b_{n-1}2^{n-1}) ab=a(b020+b121++bn12n1)=a(b020)+a(b121)++a(bn12n1)
所以我们需要取得b二进制表示的每一位,并和a进行乘法运算。这里的乘法运算有如下规则:

a*0=0;
a*1=a;

所以可以将此转换为与运算,代码如下:

public int Dhrystone(int a, int b) {
    //需要获得b的每一位
    int ans=0;
    for(int i=0;;i++){
        if((b>>i)==0)     //如果b右移i位后得到0,说明其最高位就是i位,直接break
            break;
        if(((b>>i)&1)==0)//如果得到的当前数为0,不需要运算,如果是1,那么a*1=a
            continue;
        int tem=(a)<<i;  //将a移动b当前位数
        ans=ans+tem;
    }
    return ans;
}

2. 模指数运算

我们来计算在密码学中具有较强意义的bn mod m,这里是不能先计算bn再取余的,因为bn太大了,所以这里可以将n进行和乘法中相同的拆解,则有:
b n = b a 0 2 0 + a 1 2 1 + ⋅ ⋅ ⋅ + a n − 1 2 n − 1 = b a 0 2 0 ⋅ ⋅ ⋅ b a n − 1 2 n − 1 b^n=b^{a_02^0+a_12^1+···+a_{n-1}2^{n-1}}=b^{a_02^0}···b^{a_{n-1}2^{n-1}} bn=ba020+a121++an12n1=ba020ban12n1
这里如果一个一个算分别和m取余,需要有处理,即:

令m是正整数,令a和b是整数,则:

ab mod m=((a mod m)(b mod m))mod m

所以我们可以将bn的每一项和m取余,再逐一乘,乘一次取一次余,代码实现如下:

public int Moduloremainder(int b, int n, int m) {
    int ans=1;
    int tem2=b%m;
    for(int i=0;;i++){
        if((n>>i)==0)
            break;
        if(((n>>i)&1)==0)
        {
            tem2=(tem2*tem2)%m;
            continue;
        }
        ans=(ans*tem2)%m;
        tem2=(tem2*tem2)%m;
    }
    return ans;
}

这里tem2表示b^(2的k次幂)和m取余的结果,k=0,1,2,3,····,n,实际上原理如下:
a 2   m o d   m = [ ( a   m o d   m ) ( a   m o d   m ) ]   m o d   m a^2\,mod\,m=[(a\,mod\,m)(a\,mod\,m)]\,mod\,m a2modm=[(amodm)(amodm)]modm
欢迎来我的博客看看

你可能感兴趣的:(数论)