位运算参考博客:https://blog.csdn.net/xiaochunyong/article/details/7748713
1 加法
a+b
举例实现:13+9=22
13+9
不考虑进位,结果为12
13+9
只考虑进位,结果为10
12+10
和刚好是2213
二进制为1101
,9
二进制为1001
- 不考虑进位结果为
0100
,算式为a^b
- 只考虑进位结果为
10010
,算式为(a&b)<<1
- 然后它俩继续进行运算,直到进位为
0
算法实现:
1、递归形式实现
int add(int a ,int b){
if (b == 0)
return a;
else{
//进位值
int carry = (a & b) << 1;
a = a^b;
return add(a,carry);
}
}
2、非递归形式实现
int add2(int a ,int b){
//进位值
int carry;
while (b != 0){
carry = (a & b) << 1;
a = a^b;
b = carry;
}
return a;
}
2 减法
a-b
Java负数存储是以补码形式存储的补码=反码+1
。所以反码=补码-1
即~n=-n-1=-(n+1)
所以a-b
可以化简为a+(-b)=a+~b+1
算法实现:
int subtraction(int a ,int b){
b = ~b+1;
return this.add(a,b);
}
3 乘法
a*b
举例说明:
可以看到,二进制乘法的原理是:从乘数的低位到高位,遇到1并且这个1在乘数的右起第i(i从0开始数)位,那么就把被乘数左移i位得到 temp_i 。直到乘数中的1遍历完后,把根据各位1而得到的被乘数的左移值们 temp_i 相加起来即得乘法结果。那么根据这个原理,可以得到实现代码:这里要点为:用i记录当前遍历的乘数位,当前位为1则被乘数左移i位并加到和中,同时i++处理下一位;为0则乘数右移,i++,处理下一位…直到乘数==0说明乘数中的1遍历完了。此时把和返回即可。
//乘法实现
//a 被乘数,b 乘数
int multiplication(int a,int b){
int i = 0;
int res = 0;
//乘数不为0
while (b != 0){
//处理当前位
//当前位是1
if ((b & 1) == 1){
res += (a << i);
b = b >> 1;
//记录当前是第几位
i++;
}else {
//当前位是0
b = b >> 1;
i++;
}
}
return res;
}
4 除法
a/b
除法的意义就在于:求a可以由多少个b组成。那么由此我们可得除法的实现:求a能减去多少个b,做减法的次数就是除法的商。
//除法实现
int division(int a,int b){
int res;
if(a<b){
return 0;
}else{
res=division(subtraction(a, b), b)+1;
}
return res;
}