剑指–不用加减乘除做加法
1,题目:
2,思路:
主要思想是:用位运算。
两个二进制的数相加(含有负数的)用用两个数的补码来进行相加的计算。
对于有符号数而言:
-
(1)二进制的最高位是符号位:0表示正数,1表示负数
-
(2)正数的原码、反码、补码都一样;
-
(3)负数的反码 = 它的原码符号位不变,其他位取反(0 ->1 ; 1->0 );
-
(4)负数的补码 = 它的反码 +1;
-
(5)0的反码、补码都是0;
-
(6)在计算机运算的时候,都是以补码的方式来运算的;
举例:3+(-8)用补码来计算的过程:
首先,正数的原码,反码,补码都是一样的为:
0000 0011
-8的原码:
10000 1000(这里的最高位1为符号位)
-8的反码:(也就是原码的各个位取反):
1111 0111
-8的补码(为反码+1):
1111 1000
计算:3的补码+(-8)的补码:
0000 0011 + 1111 1000=1111 1011
计算出来的是补码的,要返回去,计算出原码。
结果的反码(补码-1):
1111 1011 -1 = 1111 1010
再原码(反码的各个位取反):
1000 0101 (=十进制的-5)
计算过程图解:
3,代码:
位运算:
class Solution {
public int add(int a, int b) {
while(b != 0) { // 当进位为 0 时跳出,这个是结果往a上“加”,最后a承载的最后的结果
int c = (a & b) << 1; // c = 进位,c是承载的两数位运算以后有无进位的情况
a ^= b; // a = 非进位和,这个是结果往a上“加”,最后a承载的最后的结果
b = c; // b = 进位的情况赋值给b,由b来做循环结束的条件(当没有进位时,证明两个数的位运算已经运算结束,直接a ^= b,也就是把计算的结果给a,让a承载最后的结果)
}
return a;
}
}