zoukankan      html  css  js  c++  java
  • 剑指offer(48)不用加减乘除做加法

    题目描述

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

    题目分析

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

    那么假设我们要求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;
    }
  • 相关阅读:
    乘积最大(动规)
    电话圈(floyd)
    孪生蜘蛛
    解题报告
    最大上升子序列和
    怪盗基德的滑翔翼(还是最长x序列)
    最长公共子序列
    合唱队形(动规,最长不下降子序列)
    课堂笔记 4.6
    2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest I Lottery
  • 原文地址:https://www.cnblogs.com/wuguanglin/p/Add.html
Copyright © 2011-2022 走看看