快速乘法和快速幂法

快速乘法和快速幂法

1、快速乘法

基本原理:

利用乘法的分配率。定义a=a1+a2+a3+…,则a*b = (a1+a2+a3+…)*b。

使用快速乘法计算X*53。53的二进制表示是 110101,根据乘法分配率X*53可以表示成X*(100000*1+10000*1+1000*0+100*1+10*0+1*1)。假设X=5,可以使用下面的流转图表示。

在这里插入图片描述

可以看出 a 的状态方程为 a+=a,b的状态方程为 b>>&1,ans 的状态方程为 ans+=a。因此可以得到一下代码

代码:

//计算a*b
public int quickMultiple(int a,int b){
    int ans = 0;
    while (b>0){
        if((b&1)==1){
            ans+=a;
        }
        b=b>>1;
        a+=a;
    }
    return ans;
}

2、快速乘法取余

**背景:**在计算a * b mod c 时可能在计算a * b时越界,导致无法计算结果。

基本原理:

利用mod 的分配率。a * b mod c 可以表示为a*(b1+b2+b3+…) mod c,进一步可以转化为(a*b1 mod c +a*b2 mod c +…) mod c。

快速乘法的做法刚好是将结果转化为多个数之和,比如265 = 5*1+10*0+20*1+40*0+80*1+160*1,所以5*53 mod 3 =(5+10+20+80+160) mod 3=(5 mod 3 + 10 mod 3 + 20 mod 3 + 80 mod 3 + 160 mod 3) mod 3。因此可以得到以下代码

代码:

//计算 a*b mod c
public int quickMultiple(int a,int b,int c){
    int ans = 0;
    while (b>0){
        if((b&1)==1){
            ans=(ans+a)%c;
        }
        b=b>>1;
        a=(a+a)%c;
    }
    return ans;
}

3、快速幂法

与快速乘法相似,幂运算也可以通过转换变成乘法,比如a^9=a^(1001)=a^(1000*1+100*0+10*0+1*1)

其流转图如下:

在这里插入图片描述

与快速乘法的区别是:

  • ans初始值为1
  • a=a+a变成a=a*a
  • ans=ans+a变成ans=ans*a

代码:

//计算a^b
public int quickPower(int a,int b){
    int ans = 1;
    while (b>0){
        if((b&1)==1){
            ans=ans*a;
        }
        b=b>>1;
        a=a*a;
    }
    return ans;
}

对与每一轮的乘数又可以用快速乘法表示,比如9 = 3*3,所以又可以转化为下列程序:

//使用快速加法计算a^b
public int quickPower(int a,int b){
    int ans = 1;
    while (b>0){
        if((b&1)==1){
            ans=quickMultiple(ans,a);
        }
        b=b>>1;
        a=quickMultiple(a,a);
    }
    return ans;
}

4、快速幂取余

同理,根据快速幂的分配率可以得到a * b mod c = ((a mod c) * (b mod c)) mod c,比如39 mod 5 =((3*1 mod 5 ) * ( 9*0 mod 5) * (81*0 mod 5) *( 6561* 1) mod 5) mod 5。转化为以下代码

代码:

//计算 a^b mod c
public int quickPower(int a,int b,int c){
    int ans = 1;
    while (b>0){
        if((b&1)==1){
            ans=(ans*a)%c;
        }
        b=b>>1;
        a=(a*a)%c;
    }
    return ans;
}

对于每一轮的乘数又可以用快速乘法表示,比如9 = 3*3,所有又可以转化为下列程序:

//使用快速加法计算a^b mod c
public int quickPower(int a,int b,int c){
    int ans = 1;
    while (b>0){
        if((b&1)==1){
            ans=(quickMultiple(ans,a,c))%c;
        }
        b=b>>1;
        a=(quickMultiple(a,a,c))%c;
    }
    return ans;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值