今天有群友发了一个问题,要求不用加减符号(包括负号)来实现加减法。
分析一下,先看最简单的情况,假设1+1,按二进制算的话结果是10,可以看到从右往左的第一位变为0,第二位由于进位变为1。
第1位的值有4种,0+0=0、1+0=1、0+1=1、1+1=0,这正好符合“异或”的情况。
第2位的值来自于第一位的进位加上本身的值,进位的情况也有4种,0+0=0、1+0=0、0+1=0,1+1=1,这正好符合“与”的情况。
考虑一般性,a+b就等同于a^b + (a&b) << 1,而这又是一个加法,可递归求解,出口就是当进位为0的时候。
看个例子:
11+2
转为二进制,套用上面公式分析:
1011 + 0010
=1001 + 0100
=1101 + 0000
=1101
结果转为10进制为13
可以自己在草稿纸上多看看例子观察下。
所以Java代码实现如下:
public static int add(int a, int b){
return b == 0 ? a : add(a ^ b ,(a & b) << 1);
}
那么减法怎么搞呢?减法也能用加法表示嘛,比如a-b就等于a+(-b),但不能出现负号,我们知道Java中整型数值编码方式为补码,所以一个数对应的负数就这个数“取反加1”,so 代码如下:
public static int sub(int a, int b){
return add(a, add(~b, 1));
}
这是群友给的答案,有点意思,记录一下。