网上见到一道题目,要求用与或非等逻辑运算实现计算a+b的题目。这里我想借着这道题,记录一下自己的思路,留作以后温故。
假设 整数 a 、b都是正数
a = 6,二进制表示为 0110
b = 4 ,二进制表示为 0100
我们需要知道,上下对齐后,哪几位需要进位,哪几位不需要进位。而对于其中的某一位,只会出现这两种情况的其中一种。另外,进位后是否还需要进位,这可以放到下一轮计算再考虑。
这里我们将过程分为两个阶段。第一个阶段,判断是否需要进位,第二阶段,进位后是否还需要进位。现在先拆分第一阶段。
========================== 第一阶段 =============================
第一轮计算:按位运算(不考虑进位)
我们需要知道哪几位不存在进位。异或操作对 0^1和1^0两种情况,运算结果为1 ,0^0和1^1的运算结果为0,正好满足我们的需求
a ^ b = 0110 ^ 0100 = 0010
即从右向左,起始从1开始,只有第二位不存在进位。我们将结果记为 a1 = a ^ b
第一轮计算:进位运算
除了知道哪几位不存在进位,我们还需要知道哪几位需要进位。按位上下对齐后,只有上下都是1的时候才会有进位,而与操作正好符合要求
a & b = 0110 & 0100 = 0100
即从右向左,只有第三位存在进位,我们将其结果整体升一位(进位)即满足了要求,即(a & b) << 1
我们将结果记为 b1 = (a & b) << 1
========================== 第二阶段 ==========================
我们将a + b 运算按照 需要进位和不需要进位两种运算进行了拆分,即将a + b 转化为了 a1 + b1
下面我们需要确定 进位之后的结果 b1 与未进位的结果 a1 是否有冲突,其运算需求跟最初 a + b 的需求是一样的,因而我们可以采用第一阶段的方式完成我们的任务。
整个运算的结束标志是 没有需要进位的需求了,即b1 = 0,而最终的结果就是所有位置都稳定下来的 a1(这里的a1 或 b1 可能要经过很多次循环,可能是 a2 a3 。。。不纠结表述细节了)