1、原理java
一、化簡spa
先看一個例子:
看一下 3 + 4 的加法運算code
3 的二進制表示: 011
4 的二進制表示: 100blog
3^4 (3按位異或4)的結果是: 111 => 7
上面的到的結果是就是 3 + 4 的實際結果遞歸
再看一個例子:io
12 的二級製表示: 01100
19 的二進制表示: 10011function
12^19 的結果是: 11111 => 31class
再看一個例子:
13 的二進制表示:01101
19 的二進制表示:10011原理
13^19 的結果是: 11110 => 20二進制
經過上面的三個例子不難發現: 當二進制數的每一位加法中不發生進位時,按位異或的結果就是最終的加法結果,那麼我須要作的就是將全部的加法操做最終都簡化成沒有進位的加法操做,最終的結果就是兩個數按位異或的結果。
二、怎麼處理有進位的加法?
拆分
將兩個數的加法拆分爲 進位加法和不進位加法
看一個例子:
編號:1 2 3 4 5
------------------------
1 0 0 1 1 => 19
+ 1 1 0 1 0 => 26
--------------------------
先求只有不進位的兩個位相加的值,編號爲二、三、5這三位的加法不發生進位操做,須要進位的相加位數直接按照結果爲0處理,獲得的結果爲
編號:1 2 3 4 5
------------------------
1 0 0 1 1
+ 1 1 0 1 0
------------------------
不進位: 0 1 0 0 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
因而可知能夠將一個二進制加法拆分爲有進位的位數相加結果 和 無進位的位數相加的結果最終按位異或
三、遞歸
再看一個例子
編號: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
以上實例經過遞歸的方式能夠獲得最終的結果
2、位運算實現
經過以上幾個實例咱們明白瞭如何經過二進制的幾個步驟來實現任意整數的加法操做,如今咱們須要把這件事情用位運算進行表示。
位運算表示不進位加法:
不進位加法其實就是一個異或操做
位運算表示進位加法:
進位加法其實就是一個與操做的結果左移一位
3、代碼實現
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); }