一、原理
1、化簡
先看一個例子:
看一下 3 + 4 的加法運算
3 的二進制表示: 011
4 的二進制表示: 100
3^4 (3按位異或4)的結果是: 111 => 7
上面的到的結果是就是 3 + 4 的實際結果
再看一個例子:
12 的二級制表示: 01100
19 的二進制表示: 10011
12^19 的結果是: 11111 => 31
再看一個例子:
13 的二進制表示:01101
19 的二進制表示:10011
13^19 的結果是: 11110 => 20
通過上面的三個例子不難發現: 當二進制數的每一位加法中不發生進位時,按位異或的結果就是最終的加法結果,那么我需要做的就是將所有的加法操作最終都簡化成沒有進位的加法操作,最終的結果就是兩個數按位異或的結果。
2、怎么處理有進位的加法?
拆分
將兩個數的加法拆分為 進位加法和不進位加法
看一個例子:
編號:1 2 3 4 5
------------------------
1 0 0 1 1 => 19
+ 1 1 0 1 0 => 26
--------------------------
先求只有不進位的兩個位相加的值,編號為2、3、5這三位的加法不發生進位操作,需要進位的相加位數直接按照結果為0處理,得到的結果為
編號:1 2 3 4 5
------------------------
1 0 0 1 1
+ 1 1 0 1 0
------------------------
不進位: 0 1 0 0 1
進位兩個位相加的值,編號為1、4這三位的加法會發生進位操作,不需要進位的直接按照結果0處理,得到的結果為:
編號:1 2 3 4 5
------------------------
1 0 0 1 1
+ 1 1 0 1 0
------------------------
不進位: 0 1 0 0 1
進 位: 1 0 0 1 0 0
再將兩個結果按位異或:
不進位:0 0 1 0 0 1
進 位:1 0 0 1 0 0
------------------------
1 0 1 1 0 1 => 45
由此可見可以將一個二進制加法拆分為有進位的位數相加結果 和 無進位的位數相加的結果最終按位異或
3、遞歸
再看一個例子
編號:1 2 3 4 5
------------------------
1 0 1 1 1 => 23
+ 1 1 0 1 1 => 27
------------------------
不進位: 0 1 1 0 0 => 12
進 位: 1 0 0 1 1 0 => 38
通過一次相加得到的結果不能完全實現化簡操作,所以需要遞歸地進行化簡操作
編號:1 2 3 4 5
------------------------
1 0 1 1 1 => 23
+ 1 1 0 1 1 => 27
------------------------
不進位: 0 0 1 1 0 0 => 12
進 位:1 0 0 1 1 0 => 38
------------------------
不進位:1 0 1 0 1 0 => 42
進 位:0 0 1 0 0 0 => 8
------------------------
不進位:1 0 0 0 1 0 => 34
進 位:0 1 0 0 0 0 => 16
------------------------
不進位:1 1 0 0 1 0 => 50
進 位:0 0 0 0 0 0 => 0
以上實例通過遞歸的方式可以得到最終的結果
二、位運算實現
通過以上幾個實例我們明白了如何通過二進制的幾個步驟來實現任意整數的加法操作,現在我們需要把這件事情用位運算進行表示。
位運算表示不進位加法:
不進位加法其實就是一個異或操作
位運算表示進位加法:
進位加法其實就是一個與操作的結果左移一位
三、代碼實現
js實現:
function sum (a, b) { if (b===0) return a; return sum(a^b, (a&b)<<1) }
java實現:
public int sum(int a, int b) { if (b===0) return a; return sum(a^b, (a&b)<<1); }
