本节介绍有关位操作的算法
剑指offer中提到了一个经典面试题目,就是不用加减乘除实现两个数字的加法。
作者的代码如下:
#include<iostream>
using namespace std;
void add(int num1,int num2)
{
int sum;
int carry;
do
{
sum = num1^num2;
carry = (num1&num2) << 1;
num1 = sum;
num2 = carry;
} while (num2 != 0);
cout << num1 << endl;
}
int main()
{
add(3,24);
return 0;
}
我们来分析一下作者算法的核心,我在这里用自己语言描述一下,首先我们要知道位操作的几种运算
位操作主要有五种运算,分别是与、或、异或、左移、右移。
我们进行要知道进行两个数的加法运算就是进行两部分操作,一个是相对位置相加,一个是进位。如果我们能实现以上两项。我们先来看一下相对位置相加的操作,1加1、0加0的结果都会是0,因为1加1需要进位,所以当前位会变成0,1加0和0加1都是1,综合以上用异或运算。再看一下进位,我们要对相对位置进行1加1为1,其他的相对位置都为0,然后结果左移1位,我们可以举个例子,01和01的进位是10。
以上就是主要的理论细节。
现在我们想一下如果搞定下面的这个面试题。
如何在不用加减乘除的情况下得出一个数字6倍的值。
现在这个问题我们可以用上面的程序,
代码如下:
#include<iostream>
using namespace std;
void add(int num1,int num2)
{
int sum;
int carry;
do
{
sum = num1^num2;
carry = (num1&num2) << 1;
num1 = sum;
num2 = carry;
} while (num2 != 0);
cout << num1 << endl;
}
int main()
{
add(3 << 2, (3 << 1));
return 0;
}