问题:
Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.
Example:
Given a = 1 and b = 2, return 3.
计算2个整数相加,不能使用'+','-'操作符。
思路:
不能用操作符进行+ - 操作,很容易想到用位操作,那么位的 与 或 非 和异或,左移,右移在数学上到底有什么含义呢?
我们应该用那个位操作来代替+ - 操作呢?
首先我们先总结一下,各种位操作所代表的数学意义和位运算的特殊用途。
与操作:0&0=0; 0&1=0; 1&0=0; 1&1=1;
0001 1001
0000 1010
-----------------------------
0000 1000
得到的结果和原来的数有什么关系么?
数学意义:我们是不是可以将结果左移一位,然后将结果看成是两数之和的进位,减法,看成一个正数和一个负数的相加。
注意:负数按补码形式参加按位与运算。
-5:1111 1111 1111 1111 1111 1111 1111 1011
5: 0000 0000 0000 0000 0000 0000 0000 0101
-5&5=1
“与运算”的特殊用途:
(1)清零。如果想将一个单元清零,即使其全部二进制位为0,只要与一个各位都为零的数值相与,结果为零。
(2)取一个数中指定位
或操作:0|0=0; 0|1=1; 1|0=1; 1|1=1;
0001 1001
0000 1010
-----------------------------------------0001 1011
数学意义:
“或运算”特殊作用:
(1)常用来对一个数据的某些位进行置1操作。
异或操作:0^0=0; 0^1=1; 1^0=1; 1^1=0;
0001 1001
0000 1010
-------------------------0000 0011
数学意义:可以看成两数相加的过程,只是没有进位而已
“异或运算”的特殊作用:
(1)使特定位翻转 找一个数,对应X要翻转的各位,该数的对应位为1,其余位为零,此数与X对应位异或即可。
例:X=10101110,使X低4位翻转,用X ^ 0000 1111 = 1010 0001即可得到。
(2)与0相异或,保留原值 ,X ^ 0000 0000 = 1010 1110。
取反操作:~1=0; ~0=1;
左移操作:将一个运算对象的各二进制位全部左移若干位(左边的二进制位丢弃,右边补0)。
左移1位后 a = a * 2;
右移操作:将一个数的各二进制位全部右移若干位,正数左补0,负数左补1,右边丢弃
操作数每右移一位,相当于该数除以2。14 (即二进制的 0000 1110)右移两位等于 3 (即二进制的 0000 0011)
-14 (即二进制的 11110010)右移两位等于 -4 (即二进制的 11111100)。
无符号右移运算符(>>>):运算符把 expression1 的各个位向右移 expression2 指定的位数。右移后左边空出的位用零来填充。移出右边的位被丢弃。
变量 temp 的值为 -14 (即二进制的 11111111 11111111 11111111 11110010),向右移两位后等于 1073741820 (即二进制的 00111111 11111111 11111111 11111100)。
所以这道题:我们可以用异或操作加上与操作一块完成对两个整数的+ - 运算:首先先将两数进行异或运算得到a,然后两数进行与操作得到b,然后b右移一位后,和a再次进行异或操作,就得到了,原文题的解。
代码:
public class SumofTwoNumber {
public static void main(String[] args) {
System.out.println(MyAdd(5, -6));
}
public static int MyAdd(int num1,int num2) {
int a=num1^num2;
int b=num1&num2;
b=b<<1;
int result=a^b;
return result;
}
}