美文网首页剑指offer
48-不用加减乘除做加法-位运算(注意)

48-不用加减乘除做加法-位运算(注意)

作者: 马甲要掉了 | 来源:发表于2020-05-28 22:20 被阅读0次

    题目描述

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

    分析

    不用加减乘除做加法,我第一时间想到的就是用位运算,毕竟计算机是二进制的,所有的操作都是以位运算为基础。

    那么假设我们要求7+5=12,二进制就是111+101=1100,我们发现也就是需要处理二进制进位的问题,可是如何处理二进制进位呢?

    如果学过计算机体系结构中的进位器就知道怎么做了,不过没学过也没关系,我们可以一步一步的实验,反正位运算就那几种。

    先实验下异或:res1=111^101=010,(2)(单纯地相加各位的值,没有算进位。)

    再实验下与:res2=111&101=101,(判断是否有同1操作,同1操作需要进位。)

    或就不用试了,因为与和或是相对的。

    好像没什么头绪呀,都只是在这几位操作。

    我们发现要产生进位必不可少的就是要使用移位(这里需要使用左移<<)操作符,否则永远都是那几位在运算。

    我们知道同1时才需要进位,也就是我们先需要通过与判断同1,再左移一位来实现进位,(这个进位操作是对于所有位。)。

    res2<<1=1010,(10)

    res3=1010^010=1000,(8)

    res4=1010&010=010;(再次判断是否有同1操作需要进位。)

    我们好像得到了最高位的最终结果(从右数111的第三位和101的第三位的相加进位),但是好像其他位还可以进位。

    (进位相当于冒泡操作,还可以进位代表泡泡还没有全部冒上来)

    res4<<1=100,(4)

    res5=1000^100=1100,(我们最终要的结果。)

    res6=1000&100=0(代表没有同1操作了,也就是不用进位了)

    res6<<1=0;

    细心的读者已经发现了一点就是(5+7=10+2=8+4),也就是我们最终把5+7转化为了8+4,就是如此神奇。

    代码

    function Add(num1, num2) {
      while (num2 !== 0) {
        const tmp1 = num1 ^ num2;
        num2 = (num1 & num2) << 1;
        num1 = tmp1;
      }
      return num1;
    }
    

    知识点补充

    &:全为1为1
    |:有1则为1
    ^:不同为1
    ~:对数字取反再减1.

    相关文章

      网友评论

        本文标题:48-不用加减乘除做加法-位运算(注意)

        本文链接:https://www.haomeiwen.com/subject/iqwzahtx.html