题目描述

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

题解

public class Solution {
    public int Add(int num1,int num2) {
        int result;
        int ans;
        do {
            result = num1 ^ num2;
            ans = (num1 & num2) << 1;
            num1 = result;
            num2 = ans;
        }while (ans!=0);
        return result;
    }
}

思路

不能用加减乘除,第一步就是想位运算,我们需要先了解什么是原码,补码,反码

原码

原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值.

反码

反码是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.

补码

补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)

计算机内储存的都是补码,我们的操作也是在补码的基础上。

大概的思路就是先用^异或运算
每次异或运算都会将位数上不同的数字保留下来,比如0111(7)^1100(12),保留下来的就是1011(11)
而剩下的0100这一位,我们通过&运算,先判断出来哪一位上的数字重合,比如在这个运算中,我们是第二位都是1,接下来进行<<1运算,将这一位前移,从1000(8),于是我们将7+12拆分成了11+8,但这还没结束
1000(8)+1011(11)也要重复上述步骤,先进行异或,得到0011(3)
再进行进位,先&运算判断是哪一位,得到1000(8),在进行进位<<1,得到16(10000)
这样,就是16(10000)+3(0011) = 19


醉后不知天在水,满船清梦压星河