快速乘

因为计算机算加法的时间比算乘法的时间快得多(这貌似是学汇编才能明白原因?反正我不懂)所以我们如果能把乘法尽可能的用加法达到同样的效果,就可以缩短计算时间

我们知道,任何一个数(这里指正整数)都可以用二进制表示,所以如果把一个数拆分成他的二进制就是一堆0和1:
例如:8(D)=1000(B)
16(D) = 10000(B)
书面约定可以用字母来表示数字的对应进制
D 十进制
B 二进制
O 八进制
H 十六进制

这里就需要明白权重的概念了:
举例子来说:
532(D)有三个数字5和3和2,每一位数字所代表的含义是不同的,2在个位,就代表他是2个1,3代表3个10,5代表5个100,很好理解对不对
那么类比一下,532(D)=1000010100(B),一共有一堆0和三个1,从右往左数第一个1代表1个2*2,也就是1个2^2,(至于为什么他是从右往左数第三个数字权重确实2的2次方呢?因为从右往左数第一个数字代表的是1,也就是2的0次方。)第二个1代表1个2的4次方,第三个就代表了1个2的九次方

所以532 = 22+24+29
那么我们可以考虑用三个2次方的数来代替532去进行乘法计算
既然如此,快速乘的思想如下:
1、把乘法的其中一个数变成二进制
2、然后把1所在的权重搞清楚
3、不断把结果累加,最后得出结果

先实现第一步:变成二进制;
在这里插入图片描述
我们把除余的救国倒过来,就得到了100010100(B)
于是第一步代码就清晰了

while(b){
        if(b%2==1)
        {
        	res=res+a;//加上结果
	}

a是个啥?,就是第二步要解决的权重问题
从表格我们容易想到,不管现在是不是1,我的权重必须跟着变化,也就是说,权重的变化是在if值外的,与是不是满足if无关

while(b){
        if(b&1)
            res=res+a;
        a=a+a;//每次权重都是上一个权重的2倍
        b/=2;
    }

以上就是快速乘的核心部分,完整的代码如下

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll ab_addc(ll a,ll b)
{
    ll res=0;//这里是0,快速幂是1
    while(b){
        if(b&1)//位运算
            res=res+a;//这里是加,快速幂是乘
        a=a+a;
        b>>=1;//效果等价与/=2
    }
    return res;
}
int main()
{
    ll a,b;
    while(cin >> a >> b){
        ll MOD = ab_addc(a,b);
        printf("%lld\n",MOD);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值