前言
这里我为什么要写这篇博客,因为这道题重复做了好几遍,每次一看就感觉会了,但是第二次做发现自己是废了,不是会了。所以就有了这篇博客的发生,而且也好久没有更新过这个专栏的内容了,接下来也要好好的进行了。
(其实笔者本来是想把乘除也搞上,但是时间缘故来不及了,笔者要去赶今天的任务进度,后面有时间在写上吧)
一丶加法
首先我为什么会先实现加法呢?因为实现了加法之后,其他三种运算都是以加法为基础的。
这里我全部口述题目和解法,就不贴leetcode的链接了。
题目:给定两个整数A和B,编写一个函数返回A+B的值,但是不可以使用任何运算符。
这个题刚做的时候,我真的被卡了好久,一点思路都没有,寻思这是个啥?不用运算符号做加法?
后来看题解,理解了对应的意思。对于运算来说,在大家的学习历程中,除了运算符以外其实是还有位运算的,位运算没有使用
我们小时候刚开始做加法的时候,是怎么做的呢?打个比方
比如说做 5+ 17,总的思路是什么呢?个位相加,如果结果大于等于10,那么就保留个位的同时十位进一
第一步:这里也就是第一步各位相加也就是 5 + 7 = 12,这里满10了,所以个位保留。
第二步:10位进一,这里也就是10 + 10 = 20,最后结果也就是20 + 2 = 22。
当然这里可能比较绕,那么我们用二进制来看。
总的思路其实是一致的。
第一步:个位相加
老规矩:还是用上面的例子 5 + 17,位运算怎样能实现加法呢?
0 + 1 = 0,0 + 0 = 0, 1 + 1 产生进位所以 1 + 1 = 0,是不是很像异或?如果两个二进制位相同就是0,不相同就是1
5的二进制位是:0000 0101 17的二进制位是0001 0001
进行异或运算是多少呢? 0001 0100
然后就开始对产生了进制的二进制位进行进位操作。
那么怎么进位呢?
那么什么时候会产生进位操作?是不是两个数字的二进制位都是1的时候,就是进位的情况?
所以是不是就是我们二进制运算的按位与操作?
然后把得到的这个数字所有的二进制位往左移一位。
(5 & 12) << 1
然后把上面两步的结果相加就行。接着重复上述步骤,什么时候可以停止呢?就是当按位与操作为0的时候,就可以停止了。所以现在给出具体的代码
public static int sum(int a,int b){
int c = 0;
while(b != 0){
c = a ^ b;
b = (a & b) << 1;
a = c;
}
return a;
}
二丶减法
这里的话就沿用上面的方法就好,减去一个数等于什么呢?就等于加上这个数的相反数。
所以这里引出一个新的知识点,我们怎样用位运算去表示一个数的相反数
一个正整数N的相反数是:~N + 1
所以这里我们使用减法可以这样子做
public static int sum(int a,int b){
int c = 0;
while(b != 0){
c = a ^ b;
b = (a & b) << 1;
a = c;
}
return a;
}
//这里是求相反数
public static int subtraction(int a){
return sum(~a,1);
}
然后比如说我们要求a - b,那么就
System.out.println(sum(a,subtraction(b)));
就好了。