劍指offer-47:不用加減乘除作加法

參考:https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html 《原碼,反碼,補碼 詳解》html

題目描述

寫一個函數,求兩個整數之和,要求在函數體內不得使用+、-、*、/四則運算符號。

解題思路

不能使用加減乘除,個人第一反應就是使用 位運算 和 二進制字符串判斷 。二進制字符串從末尾到首位一位位判斷,也是能得出結果的,可是代碼太長,判斷多種狀況,太麻煩了。這並非一個聰明的方法,捨棄了。函數

 

另外一種方法是位運算。一個數在計算機中會先轉成二進制,正數使用原碼,負數使用補碼,而後進行加減操做。例如計算機中有兩個正整數 a 和 b,a + b 則是 a 的原碼加上 b 的原碼;a - b = a + (-b),即 a 的原碼加上 (-b) 的補碼。具體的計算過程,請看第一行的參考連接,講的很詳細。在Java中,負數的二進制也是使用補碼錶示的,因此,只須要考慮如何完成加法便能解決問題。spa

 

首先看兩個例子,二進制是如何進行加法的。從兩個例子中能夠發現,在沒有進位的狀況下,兩個二進制相加,實際上進行了異或操做。在有進位的狀況下,先進行異或,獲得的是不包含進位的結果 (A)。而後兩個二進制再進行位與,獲得只帶進位的結果 (B)。而後重複以上兩個操做,將 (A) 與左移一位的進位 (B) 異或,獲得結果 (C);將 (A) 與左移一位的進位 (B) 位與,獲得結果 (D);一直到最後位與的結果爲0,即沒有進位,終止循環。那麼在最後 位與 以前的一步 異或 就是最終的結果。code

例子1: 10 + 5 = 15

    1 0 1 0
+   0 1 0 1
--------------
    1 1 1 1
例子2: 9 + 5 = 14

   1 0 0 1 1 0 0 1 1 0 0 1 1 1 0 0 1 1 0 0
+  0 1 0 1 異或  0 1 0 1    位與 0 1 0 1 異或 0 0 0 1 0 (左移一位) 位與 0 0 0 1 0
-------------- --------------- -------------- ----------------- -------------------
   1 1 1 0 (A) 1 1 0 0 (B) 0 0 0 1 (C) 1 1 1 0 (D) 0 0 0 0

 代碼以下:htm

1 public int Add(int num1,int num2) {
2     while (num2 != 0) {
3         int tmp = num1 ^ num2;
4         int carry = (num1 & num2) << 1;
5         num1 = tmp;
6         num2 = carry;
7     }
8     return num1;
9 }
相關文章
相關標籤/搜索