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); }