剑指offer-不用加减乘除做加法-JavaScript

题目

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

 

思路

位运算

按位与&,按位或|, 按位异或^

剑指offer-不用加减乘除做加法-JavaScript_第1张图片

使用位运算实现加法:

1、一位加法

剑指offer-不用加减乘除做加法-JavaScript_第2张图片
难点:如何解决进位问题?

问题:没有采取进位操作导致运算错误

剑指offer-不用加减乘除做加法-JavaScript_第3张图片
在位运算中,我们用“<<”表示向左移动一位,也就是“进位”。那么我们就可以得到如下的表达式: 

   ( x & y ) << 1

拥有了两个基本表达式:

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

2、二位加法

  1. 计算a和b的无进位和(异或运算),和进位(与运算然后左移1位)
  2. 如果进位不为0,则说明a+b的结果等于无进位和+进位,此时,把无进位和作为a,进位作为b,继续计算
  3. 如果进位等于0, 说明此时a+b的结果就等于无进位和,返回无进位和即可。

例子:

  • 正确的加法计算: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

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,所以没有要处理的进位了)

更高位加法:依上边类推

 

JavaScript代码

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

你可能感兴趣的:(算法)