不用加减乘除做加法

1 题目描述

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

1.1 位运算

 使用位运算实现加法

1.1.1 一位加法

普通加法异或
1 + 1 = 01^1 = 0 (错误)
1 + 0 = 11^0 = 1 (正确)
0 + 1 = 10^1 = 1 (正确)
0 + 0= 00^0 = 0 (正确)

问题:没有采取进位操作导致运算错误
难点:如何解决进位问题?

与运算
1 & 1 = 1(进位)
1 & 0 =0 (不进位)
0 & 1 = 0 (不进位)
0 & 0 = 0(不进位)

在位运算中,我们用"<<" 表示向左移动一位,也就是"进位"。可得到如下的表达式:

     1. (x & y)<<1

拥有了两个基本表达式:

  1. 执行加法 x^y
  2. 进位操作 (x & y)<<1

1.1.2 二位加法

例子:

  正确的加法计算:11+01=100

 使用为运算实现二位加法:

  1. 按位加法:res1 = 11 ^ 01 =10
  2. 与运算进位:res2 =(11 & 01) <<1 = (01) << 1=010
  3. res1 ^ res2 = 10 ^ 010 = 00
  4. (10 & 10) << 1 = 100

1.1.3 更高位的加法

继续推理可以得出三位数的加法只需重复的计算三次得到第一个表达式的值就是计算出来的结果。

三位加法:

  1. 101 ^ 111 = 0010 (没有处理进位的加法)
    (101 & 111)<< 1 = 101 << 1 = 1010 (此处得到哪一位需要加上进位,为1的地方表示有进位需要加上)
  2. 0010 ^ 1010 = 1000 (没有处理进位的加法 + 进位 = 没有处理进位的加法)
    (0010 & 1010) << 1 = 0010 << 1 = 00100(查看是否有新的进位需要处理)
  3. 1000 ^ 00100(没有处理进位的加法 + 进位 = 没有处理进位的加法)
    (1000 & 00100)<<1 =00000<<1=000000(进位为0,所以没有要处理的进位了)

1.1.4 代码

public class Solution {
    public int Add(int num1,int num2) {
        int result = 0;
        int carry = 0;
        do{
            result = num1 ^ num2;       //不带进位的加法
            carry = (num1 & num2) << 1; //进位
            num1 = result; 
            num2 = carry;  
        }while(carry != 0); // 进位不为0则继续执行加法处理进位
        return result;
    }
}

时间复杂度:O(1) // 最高执行32次 int 大小32位
空间复杂度:O(1)

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值