不使用算术运算符计算两数之和

计算两个数之和,本来是一件小学生就会做的事,不对,幼儿园学生都会!可是偏偏有些面试官,要求计算两个数之和不能用加号“+”,这不是故意刁难人嘛。可是为了offer,还是得硬着头皮去做。今天就谈一谈怎么在不使用四则运算符号的前提下做加法。
虽然我们人做四则运算喜欢使用算术运算符,可是计算机呢?对计算机而言,一切皆是一串二进制的数。
既然是二进制数,每个bit就可以通过:& (与)、^(异或)、<<(移位)等进行运算。
最简单的集中情况:
在这里插入图片描述
于是,聪明的你很快就能想到(想不到也没办法~)上面的加法不证实异或运算的结果吗?
因为:0 ^ 0=0 ,0 ^ 1=1,1 ^ 1=0
所以,计算两个数a、b之和,直接用a^b就能得到在不考虑进位情况下的和。但是既然是加法,不考虑进位好像还是不太好,如何考虑进位呢?
先来做一下,我们最熟悉的十进制加法运算:
在这里插入图片描述
从上面可以看出来,两个数之和=两数之和(不考进位)+进位数 (为了方便描述将1 以及0101成为进位数)
如果进位发生在个位,进位在十位
如果进位发生在十位,进位在百位……
一次类推,因此需要将进位数乘以10,从位运算的角度,就是将进位数左移1位
明白了10进制运算的原理,二进制也是一样
在这里插入图片描述
由于进位发生在最左边1为,但是进位在左边第2为,因此要将进位数左移1位后相加。
1100+(0010<<1) = 1110

通过上面的分析,可以得出如下结论:
两个数相加的和,等于两个数异或结果加上进位数左移1位后的结果

但是在实际计算的时候,由于两个数异或的结果加上进位数左移1位的结果,还是会产生新的进位,所以需要做反复的进位计算,直到最后进位数为0。

那么问题来了?最后进位数一定会为0吗?什么时候会为0。答案是肯定的!
例如0101+1001,计算过程如下:
第一次计算:0101+1001=1100 进位为0001(左移移位为00010
第二次计算:1100+00010=1110 进位为0
第一次计算是,最左边1位会产生进位。
第二次计算时,由进位数会左移1位,因此最左边的数一定0,计算时不会产生进位。因此,每计算一次,就可以让从左到到至少减少1位不会进位,最终进位数会变为0。

最后附上代码(假定结果不会溢出):

int add(int a,int b)
{
    int sum=a;
    while(b)
    {
        int carry=sum&b;//获取进位的各个bit
        sum^=b;//计算sum+b结果,不考虑进位
        b=((unsigned int )carry)<<1;//由于之前没有考虑进位,后续需要把进位结果继续与sum相加
        //使用unsigned int 防止int类型溢出
    }
    return sum;
}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值