JZ48 不用加减乘除做加法

题意分析

自己实现一个没有使用加减乘除的加法。

示例输入:1,2
返回:1+2=3

题解一:(投机取巧):

不建议使用,没有学习到只是点。

int Add(int num1, int num2) {
    vector<int> v = {num1, num2};
    return accumulate(v.begin(), v.end(), 0);
}

题解二(位运算):

想象小学所用的算术加法流程,指定位数字相加,进位。这里我们把提供的数字当做二进制数,模拟二进制加法即可。比如3+7,过程如下:

图片说明

模拟一个二进制加法即可。但是上面取模加法也不能使用。那么应该考虑怎么用位运算代替。

以上面例子:当3和7相加的时候,二进制表达末位均为1,该位上的结果可以表示为。由于需要进位,我们可以考虑怎么把这个进位加到加法某个操作书上。

举个例子,在10进制的时候,33+88,将每个数位上的值相加得到了11,进位的结果为11。考虑到进位后,扩大了10倍,进位得到的大小为110,因此应该将11与110相加。再把每个数位相加,得到121.进位值为0。没有进位,那么最后的结果为121。

在二进制中,每个数位值相加的结果可以表示为,进位的结果可以表示为。2表示2进制下扩大两倍,相当于10进制小乘10..

一直到b变为0。那么a就是最后的结果。

对于负数的情况,计算机中使用了补码作为负数在计算机中的存储。其使加法和减法统一了起来。因此模拟的二进制加法也是可行的。

int add(int a, int b) {
    while (b != 0) {
        int c = (a & b) << 1; 
        a ^= b; 
        b = c;
    }
    return a;
}