a+b

不使用加法计算a+b的值

首先考虑十进制加法中,如8+15:

1、不考虑进位:各位相加:个位得8+5=13,个位为3;十位得0+1=1;结果为13

2、考虑进位:个位进位为10

3、1和2中的结果相加得13+10=23

按照上述思想考试二进制加法中:如1000+1111

1、不考虑进位:各位相加:1+1=0,1+0=1,0+1=1,0+0=0,与位运算中的亦或操作相同 a^b

2、考虑进位:显然只有1+1会出现进位,相对于这位的进位为10,即把与运算的结果往左移一位 (a&b)<<1

3、1和2中的结果相加直到不产生进位

以上分析来自lintCode

根据以上分析,我们可以得出一个结论:a+b = f(a+b) + m(a+b)
其中f(a+b)表示无进位的a+b,比如上面的13,m(a+b)表示进位结果,比如上面的10

在位运算中,异或运算通常也叫做无进位的加法,与运算刚好可以用来计算进位结果(因为只有 1&1 == 1,只有 1 + 1 会进位),所以我们又可以得出以下公式:a+b = a^b + (a&b)<<1,由于不能用加法,这个公式我们可以很容易的用递归实现:

int sum(int a, int b)
{
    if (b == 0) {
        return a;
    }
    int c = a^b;
    int d = (a&b)<<1;
    return sum(c, d);
}

非递归版本
前有公式:a+b = a^b + (a&b)<<1,其中 a 对应于 a^b ,b 对应于 (a&b)<<1,因为 ^ 在这里是加法,所以 a 代表无进位加法结果,b 代表进位信息,当没有进位信息时(b==0),计算结束,据此,我们可以写出如下非递归代码:

int sum(int a,int b)
{
    /**
     先计算进位结果 c
     然后计算无进位结果 a
     如果有进位,设置给b,进入下一次计算
     */
    while (b != 0) {
        int c = (a&b)<<1;
        a = a^b;
        b = c;
    }
    return a;
}

PS:对于递归运算,千万不要试图用大脑来计算每一次递归的结果!!!

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 先上代码 举个例子:例如输入3和63 二进制转码为 00116 二进制转码为 0110 a^b 即 3^6 就为 ...
    了3乐阅读 3,674评论 0 0
  • lintcode算法题 1.A + B 问题 描述给出两个整数 a和 b, 求他们的和。你不需要从输入流读入数据,...
    阿丹_90阅读 4,276评论 0 1
  • A+B问题 描述 给出两个整数a和b, 求他们的和, 但不能使用 + 等数学运算符。 思路: 1、 采用二进制进...
    奇迹迪阅读 2,929评论 0 2
  • 规律来源:(1): 0+0=0;(2):0+1=1;(3):1+0=1;(4) : 1+1=10; A^B 对每...
    爱学习的小黄牛阅读 2,981评论 0 1
  • Description:Write a function that add two numbers A and B...
    流浪山人阅读 1,748评论 0 0