如何在程序中不用加号实现加法_如何不使用“+”号实现加法操作?

答案里面很多都是直接甩代码, 我来解释一下吧。

傻瓜都能懂系列之 - 不使用 +号实现加法:

对于这个问题,与其说是 不使用+ 号 , 还不如说是用更底层的, 用指令层级的操作来实现 +法。

+号这个东西本来就不是天然存在的,它本来就是用位运算实现的,我们做的只不过是自己实现一遍而已。

我们知道电路这个东西,最直接的,最好处理的就是逻辑,门电路中有 AND,OR, XOR 等操作,在实现上也很简单,可是我们真正要求计算机做的却不只是单纯的逻辑操作,而是更多的数学运算,比如加法,减法等。

那身为计算机设计者,我们就要解决一个问题,如果用最基本的 AND,OR,XOR,Shift 等电路上容易实现的操作来实现更高层次的数学运算 - 加法?

所谓XOR, 即是 exclusive or , 说白了就是只有两个输入中的一个为 1 另一个为 0 的时候, 才输出 1, 都是 1 或都是 0 就输出 0, 这在硬件上实现并不难。

所谓 Shift , 即是对一系列二进制数的左移或右移,比如 1000 , 右移一位,就变成 0100,左移一位,就变成 10000,当然前提是位数要至少是五位,硬件实现也不难。

所谓 AND, 就是且 。

那么我们现在试图通过上面说的这三种运算构建出高级语言呈现给我们的,开箱即用的+ 运算符。

不管是多少进制,相加的原理都是加,进位。

但是二进制很特殊,因为它是二进制,所以很多操作可以和逻辑运算形成某种对应。

比如 101 + 111,我可以分成两部分算,一部分算”进位“,一部分算非进位那部分。

如果觉得抽象,我用十进制先举一个例子。

57 + 44 : 个位 7+4 >=10 , 进位 1, 十位 5 + 4 < 10, 进位 0, 那么进位的部分就是 10, 为什么是 10 而不是 1 呢? 因为进位本来就是向高的地方进位, 所以要 "左移一位"

非进位的那部分, 个位为 1, 十位为 9, 所以就是 91, 那么结果就是 91 + 10, 好, 那么现在问题就转换成了 91 + 10 了 —》

91 + 10:再次调用之前的操作, 进位的部分是 100, 非进位的部分是1, 那么就是 100 + 1 -》

100 + 1:进位的部分为0,非进位部分为 101, 至此,检测到进位部分为 0 ,则计算结束。

那么对于二进制来讲,计算非进位的部分,我们会发现其实就是 XOR操作符就能解决,因为1和1相加,0和0相加,结果都是0,1和0相加结果是1,举例,而进位,则用AND操作符就解决, 因为当且仅当 1 和 1 都存在时, 进位才为 1, 所以是 AND。

1011 + 11: 非进位:1011 XOR 11 = 1000 进位: (1011 AND 11) << 1 = 110

1000 + 110: 非进位: 1000 XOR 110 = 1110 进位: (1000 AND 110) << 1 = 0

检测到进位部分为 0 , 所以结果就是 1110.

那么写成代码,就是一个简单的recursive:

int getSum(int a, int b) {

return b == 0 ? a : getSum(a ^ b, (a & b) << 1);

}

其中, ^ 是 XOR操作符, & 是 AND 位操作符。

理解了这个代码之后,事实上给你几个逻辑门,你就可以自己拼一个加法计算电路出来了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值