不用加减乘除做加法

题目

写一个函数,求两个整数之和,要求在函数体内不得使用+、-、*、/四则运算符号。

解析

位运算符的应用,以下是六种常见的位运算符:

    运算符             含义          语法                                应用
       <<             左移         a<<x            二进制a左移x位,相当于乘以2^x
       >>             右移         a>>x            二进制a右移x位,相当于除以2^x
        &      按位做与运算         a&b                            11得1
        |      按位做或运算         a|b                            00得0
        ^    按位做异或运算         a^b                实质上是二进制不进位的加法
        ~         按位取反         ~a            取反等于2^n-a(n为a的二进制位数)

^运算符的一个重要应用就是二进制不进位的加法,而对于进位问题,我们观察到&运算符有11得1的性质,两个数刚好都是1时产生进位,进位数为1,然后将数字左移一位。所以两个数相加的结果就应该是原位+进位。

以下摘自网友的思路:

----------------------------------------------------------------------------------------------------------------------------------------------------------
我们可以用三步走的方式计算二进制值相加: 5-101,7-111

第一步:相加各位的值,不算进位,得到010,二进制每位相加就相当于各位做异或操作,101^111。

第二步:计算进位值,得到1010,相当于各位做与操作得到101,再向左移一位得到1010,(101&111)<<1。

第三步重复上述两步, 各位相加 010^1010=1000,进位值为100=(010&1010)<<1。

继续重复上述两步:1000^100 = 1100,进位值为0,跳出循环,1100为最终结果。

再如:

13+11 = ?;

13 的二进制      1 1 0 1                     -----a        13

11 的二进制      1 0 1 1                     -----b        11  

 

 (a&b) <<1  ->   1 0 0 1 0                  -----d         18

          a^b  ->     0 1 1 0                     -----e          6

 

 (d&e) <<1  ->   0 0 1 0 0                   ------f         4

          d^e  ->  1 0 1 0 0                      -----g        20

 

 (f&g) <<1  ->   0 1 0 0 0                    ------h        8

          f^g  ->  1 0 0 0 0                      ------i           16

 

 (h&i) <<1  ->   0 0 0 0 0                     ------h        0       ---- --------退出循环

          h^i  ->  1 1 0 0 0                       ------i           24

----------------------------------------------------------------------------------------------------------------------------------------------------------

class Solution {
public:
    int Add(int num1, int num2)
    {
      while(num1)   //进位不为0时一直循环(当num1的初始值为0时相加结果就是num2)
      {
          int num3=num1;
          num1=(num1&num2)<<1;
          num2=num2^num3;
      }
        return num2;
    }
};

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值