(笔试题)只用逻辑运算实现乘法运算
题目:
如题所示
思路:
看一个实例,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; }