zl程序教程

您现在的位置是:首页 >  其它

当前栏目

(笔试题)只用逻辑运算实现乘法运算

实现 运算 笔试 乘法 只用 逻辑运算
2023-09-14 08:59:06 时间

题目:

如题所示

思路:

看一个实例,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;
}