资讯专栏INFORMATION COLUMN

如何用位运算实现整数的加减法

Worktile / 2133人阅读

摘要:假设,,先把,转化为二进制,那么,,二进制的加法是逢进,如果两个数的同一位的基数分别是和,那么这个位上的基数为如果都是,则基数为如果都是,则基数为。

今天刷Leecode刷到第371题:

Sum of Two Integers

Calculate the sum of two integers a and b, but you are not allowed to use the operator + and -.

Example:
Given a = 1 and b = 2, return 3.

Credits:
Special thanks to @fujiaozhu for adding this problem and creating all test cases.

Subscribe to see which companies asked this question

题目要求我们在不使用加减操作符的情况下得到两个整数的和。由于减法和乘除法都是基于加法操作的,所以此题不能考虑‘+’、‘-’、‘*’、’/‘这四个操作符,我们使用位运算来得到两个数的和。
假设a = 15, b = 9, 先把a,b转化为二进制,那么a = 1111,b = 1001,二进制的加法是逢2进1,如果两个数的同一位的基数分别是0和1,那么这个位上的基数为1;如果都是1,则基数为0;如果都是0,则基数为0。这种方式类似于位运算中的异或,只有两个数字不等的时候结果才为1,那我们是不是可以直接用a ^ b来得到a + b的值呢?当然不行,当同一位上两个基数都为1时,此时该位上的基数变为0,但是应该在它的左边一位加1,异或运算并没有给它加1,所以我们还得把逢2进1的那个1加进去,01 + 01 = 10,所以两个数有一个位上的基数都是1的时候相加就类似于与运算,但是要把结果左移一位,因为它是在比它高一位的地方进1,相当于是乘以2了。于是两个二进制的加法就转化成了两部分,一部分是两个数同一位上的基数同为1的值,这部分的值用(a & b)<<1 可以得到,另一部分的值可以用异或得到,即 a ^ b,所以 a + b = a ^ b + (a & b)<<1.
在上一例中,

(a & b)<<1 = (1111 & 1001)<<1 = 10010;
 a ^ b = 1111 ^ 1001 = 110;
 a + b = 10010 + 110 = 11000 = 24

完整的代码如下:

var getSum = function(a, b) {
    //注意"+"的优先级大于"<<",所以要先把(a & b)<<1括起来
    var s = (a ^ b) + ((a & b)<<1)
    return s 
};

异或还有一个特点就是,一个整数与0异或的结果就等于它自己,它和自己异或等于0,这个结论能帮我们解决第136题。

[Single Number][2]

Given an array of integers, every element appears twice except for one. Find that single one.

Note:
Your algorithm should have a linear runtime complexity. Could you implement it without using extra memory?

Subscribe to see which companies asked this question

要找出一个数组里唯一的那个数,这时候我们很自然就想到了异或的特点,即:

a ^ 0 = a
a ^ a = 0
a ^ b ^ a = a ^ a ^ b = 0 ^ b = b

所以这道题我们利用for循环将数组里的所有元素异或,最终得到的就是那个只出现了一次的数,代码如下:

var singleNumber = function(nums) {
    var result = 0
   for(var i = 0; i < nums.length; i++) {
       result = result ^ nums[i] 
   } 
   return result
};

可见有时候位运算的作用也很大呢!

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80542.html

相关文章

  • 【手把手带你刷LeetCode】——15.剑指offer之不用加减乘除做加法(运算

    摘要:前言今天是力扣打卡第天天天做递归做烦了,换换脑子,嘿嘿。原题不用加减乘除做加法题目描述写一个函数,求两个整数之和,要求在函数体内不得使用四则运算符号。补码的优势加法减法可以统一处理只有加法器。 【前言】 今天是力扣打卡第15天! 天天做递归做烦了,换换脑子,嘿嘿。 原题: 不用加减...

    QLQ 评论0 收藏0
  • 「干货」细说 Javascript 中浮点数精度丢失问题(内附好课推荐)

    摘要:前言最近,朋友问了我这样一个问题在中的运算结果,为什么是这样的虽然我告诉他说,这是由于浮点数精度问题导致的。由于可以用阶码移动小数点,因此称为浮点数。它的实现遵循标准,使用位精度来表示浮点数。 showImg(https://segmentfault.com/img/remote/1460000018981071); 前言 最近,朋友 L 问了我这样一个问题:在 chrome 中的运算...

    senntyou 评论0 收藏0
  • Javascript 基本概念(操作符)

    摘要:对于有符号的整数,第一位是符号位正数,负数,后位表示数值。正数二进制表示,没有用到的位补,如用二进制表示为,第一位是符号位,后位均用补位,是有效位。按位非求反码,本质是求操作数的负值减一。 showImg(https://segmentfault.com/img/remote/1460000014827639); 操作符 一元操作符 只能操作一个值的操作符叫一元操作符 ++ and ...

    Paul_King 评论0 收藏0
  • js-数据运算

    摘要:跳过第二个运算子的机制,被称为短路有些程序员喜欢用它取代结构等价于运算符可以多个连用返回第一个布尔值为的表达式的值。 一、运算符概述 1、定义 JavaScript中运算符主要用于连接简单表达式,组成一个复杂的表达式 2、运算符类别 算数运算符 赋值表达式 比较表达式 布尔运算符 位运算符 二、算数运算符 1、加法运算符(Addition):x + y 加法运算符是在运行时决定,到...

    sf190404 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<