题目:
如题所示
思路:
看一个实例,1011*1010,由于二进制的特殊性,可以将该乘法运算表达式拆分为两个运算,1011*1000以及1011*0010的和,对于二进制运算,左移一位,等价于乘以0010,左移三位,等价于乘以1000,因此两者的乘积为10110+1011000之和,即为1101110.
通过上述例子,可知一个乘法运算可以转化为一系列的移位和加法运算来完成。如a*b
最后一个1可通过b&~(b-1)求得,可通过b&(b-1)去掉,为了高效得到左移的位数,可以提前计算并保存在map中。
代码:
#include <iostream>
#include <map>
using namespace std;
int add(int num1,int num2){
if(num1==0)
return num2;
if(num2==0)
return num1;
int num_xor=num1^num2;
int carry=(num1&num2)<<1;
return add(num_xor,carry);
}
int multiply(int a,int b){
bool neg=false;
if(a>0 && b<0){
neg=true;
b=-b;
}
if(a<0 && b>0){
neg=true;
a=-a;
}
if(a<0 && b<0){
a=-a;
b=-b;
}
map<int,int> bit_map;
for(int i=0;i<32;i++)
bit_map.insert(pair<int,int>(1<<i,i));
int sum=0;
while(b>0){
int last_bit=bit_map[b&~(b-1)];
//sum+=(a<<last_bit);
sum=add(sum,a<<last_bit);
b=b&(b-1);
}
if(neg)
sum=-sum;
return sum;
}
int main()
{
int a=11,b=-10;
cout << multiply(a,b) << endl;
return 0;
}