这篇文章不讲一元运算符,也就是 + 、-、 *、 /、 =、 ||、 &&、 !这些。

位运算符是在数字底层(即表示数字的32个数位)进行操作的。

有符号整数使用 32 位的前 31 位表示整数值。第 32 位表示数值的符号,如 0 表示正,1 表示负。这一位称为符号位。

正值以真正的二进制格式存储,即 31位中的每一位都代表 2 的幂。第一位(称为第 0 位)表示 2的0次幂,第二位表示 2的1次幂,依此类推。如果一个位是空的,则以0填充,相当于忽略不计。比如,数值18的二进制格式为00000000000000000000000000010010,或更精简的 10010。后者是用到的 5 个有效位,决定了实际的值。

负值以一种称为二补数(或补码)的二进制编码存储。一个数值的二补数通过如下 3 个步骤计算得到:

(1) 确定绝对值的二进制表示(如,对于-18,先确定 18 的二进制表示);
(2) 找到数值的一补数(或反码),换句话说,就是每个 0 都变成 1,每个 1 都变成 0;
(3) 给结果加 1。

基于上述步骤确定-18 的二进制表示,首先从 18 的二进制表示开始
0000 0000 0000 0000 0000 0000 0001 0010
然后,计算一补数,即反转每一位的二进制值:
1111 1111 1111 1111 1111 1111 1110 1101
最后,给一补数加 1:
1111 1111 1111 1111 1111 1111 1110 1101
1
---------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110

所以,-18 的二进制表示就是 11111111111111111111111111101110。

1. 按位非(~)
(~)是返回数值的一补数。

let num1 = 25;      // 二进制 00000000000000000000000000011001
let num2 = ~num1; // 二进制 11111111111111111111111111100110
console.log(num2); // -26

可以看出,(~)可以当做是这个数的绝对值取反减1的二进制数;
*** 小技巧: 对一个小数两次按位非,可以得到取整效果。

console.log(~~2.5); // 2
2. 按位与(&)
按位与操作符用和号(&)表示,有两个操作数。本质上,按位与就是将两个数的每一个位对齐,然后基于真值表中的规则,对每一位执行相应的与操作。
tips: 是转化成二进制的对应位数下的值是否一致;
let result = 25 & 3;
console.log(result); // 1 25 和 3 的按位与操作的结果是 1。为什么呢?看下面的二进制计算过程:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
& = 0000 0000 0000 0000 0000 0000 0000 0001 如上所示,25 和 3 的二进制表示中,只有第 0 位上的两个数都是 1。于是结果数值的所有其他位都会以 0 填充,因此结果就是 1。

*** 小技巧:和1进行按位&操作来判断其奇偶性,比如 num&1,若为1,则num是奇数;若为0,则num是偶数。

3. 按位或(|)
按位或操作符用管道符(|)表示,同样有两个操作数。按位或操作在至少一位是 1 时返回 1,两位都是 0 时返回 0。
let result = 25 | 3;
console.log(result); // 27 可见 25 和 3 的按位或操作的结果是 27: 25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
| = 0000 0000 0000 0000 0000 0000 0001 1011
在参与计算的两个数中,有 4 位都是 1,因此它们直接对应到结果上。二进制码 11011 等于 27。
4. 按位异或(^)
按位异或用脱字符(^)表示,同样有两个操作数。
按位异或与按位或的区别是,它只在一位上是 1 的时候返回 1(两位都是 1 或 0,则返回 0)。
let result = 25 ^ 3;
console.log(result); // 26
可见,25 和 3 的按位异或操作结果为 26,如下所示:
25 = 0000 0000 0000 0000 0000 0000 0001 1001
3 = 0000 0000 0000 0000 0000 0000 0000 0011
---------------------------------------------
^ = 0000 0000 0000 0000 0000 0000 0001 1010
两个数在 4 位上都是 1,但两个数的第 0 位都是 1,因此那一位在结果中就变成了 0。其余位上的 1
在另一个数上没有对应的 1,因此会直接传递到结果中。二进制码 11010 等于 26。

  

5. 左移(<<)
左移操作符用两个小于号(<<)表示,会按照指定的位数将数值的所有位向左移动。比如,如果数值 2(二进制 10)向左移 5 位,就会得到 64(二进制 1000000)

左移会保留它所操作数值的符号。比如,如果-2 左移 5 位,将得到-64,而不是正 64。

6. 有符号右移(>>)
有符号右移由两个大于号(>>)表示,会将数值的所有 32 位都向右移,同时保留符号(正或负)。有符号右移实际上是左移的逆运算。比如,如果将 64 右移 5 位,那就是 2。

 7. 无符号右移(>>>)

无符号右移用 3 个大于号表示(>>>),会将数值的所有 32 位都向右移。
对于正数:无符号右移与有符号右移结果相同。仍然以前面有符号右移的例子为例,64 向右移动 5 位,会变成 2。
对于负数:因为负数是其绝对值的二补数,所以右移之后结果变得非常之大。

let num= -64; // 等于二进制 11111111111111111111111111000000
let result = num >>> 5; // 等于十进制 134217726

js 操作符 —— 位操作符详解的更多相关文章

  1. C#中缓存的使用 ajax请求基于restFul的WebApi(post、get、delete、put) 让 .NET 更方便的导入导出 Excel .net core api +swagger(一个简单的入门demo 使用codefirst+mysql) C# 位运算详解 c# 交错数组 c# 数组协变 C# 添加Excel表单控件(Form Controls) C#串口通信程序

    C#中缓存的使用   缓存的概念及优缺点在这里就不多做介绍,主要介绍一下使用的方法. 1.在ASP.NET中页面缓存的使用方法简单,只需要在aspx页的顶部加上一句声明即可:  <%@ Outp ...

  2. js调试工具Console命令详解

    这篇文章主要介绍了js调试工具Console命令详解,需要的朋友可以参考下   一.显示信息的命令 复制代码 代码如下: < !DOCTYPE html> < html> &l ...

  3. JQ的offset().top与js的offsetTop区别详解

    一.前言 最近在做一个图片懒加载的插件,就纵轴(Y轴)而言,我需要时时获取图片的上偏移量,好判断是否已进入视图区域,而我所理解的是offsetTop应该是跟offset().top一样的,然后陷入了因 ...

  4. JQ的offset().top与JS的getBoundingClientRect区别详解,JS获取元素距离视窗顶部可变距离

     壹 ❀ 引 我在 JQ的offset().top与js的offsetTop区别详解 这篇博客中详细分析了JQ方法offset().top与JS属性offsetTop的区别,并得出了一条offset( ...

  5. Java自学-操作符 位操作符

    Java的位操作符 位操作符 在实际工作中使用并不常见. 示例 1 : 一个整数的二进制表达 位操作都是对二进制而言的,但是我们平常使用的都是十进制比如5. 而5的二进制是101. 所以在开始学习之前 ...

  6. JS中this关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 阅读此文章,还需要心平气和的阅读完,相信一定会有所收获,我也会不定期的发布,分享一些文章,共同学习 首先,必须搞清楚在JS里面,函数 ...

  7. JS 中 this 关键字详解

    本文主要解释在JS里面this关键字的指向问题(在浏览器环境下). 首先,必须搞清楚在JS里面,函数的几种调用方式: 普通函数调用 作为方法来调用 作为构造函数来调用 使用apply/call方法来调 ...

  8. <转>C++位运算详解

    原文转自:http://www.crazycpp.com/?p=82 前言 以前收藏过一篇讲C++位操作的文章,这次博客搬家,以前的数据都没有保留,整理谷歌网站管理后台的时候,发现不时的还有网友有在查 ...

  9. 原生JS:String对象详解

    @import url(http://i.cnblogs.com/Load.ashx?type=style&file=SyntaxHighlighter.css);@import url(/c ...

  10. Js apply() call()使用详解

    Js apply方法详解我在一开始看到javascript的函数apply和call时,非常的模糊,看也看不懂,最近在网上看到一些文章对apply方法和call的一些示例,总算是看的有点眉目了,在这里 ...

随机推荐

  1. 一定要用Photoshop?no!动手用Python做一个颜色提取器! ⛵

    作者:韩信子@ShowMeAI Python3◉技能提升系列:https://www.showmeai.tech/tutorials/56 计算机视觉实战系列:https://www.showmeai ...

  2. 浅谈 Java 和 Python 的反射

    反射这个词我一直没搞懂,也不知道为什么需要反射,也不知道反射到底做了什么.所见所闻逐渐丰富之后,开始有点儿懂了. 先不管反射这个词是什么意思.Java 里面有反射,Python 里面也有反射,但是不太 ...

  3. python中的字符串(1)

    1.大小写的转换 upper()/lower() 转成大写.upper() 转成小写.lower() 返回的是字符串 2.是否是数字 isdigit() 返回的布尔值 3.去除字符串的空白字符 str ...

  4. Kubernetes(k8s)存储管理之数据卷volumes(二):hostPath数据卷

    目录 一.系统环境 二.前言 三.hostPath数据卷 3.1 hostPath数据卷概览 3.2 创建有hostPath卷的pod 一.系统环境 服务器版本 docker软件版本 Kubernet ...

  5. 《HTTP权威指南》– 16.重定向与负载均衡

    重定向 重定向 的目标是尽快地将HTTP报文发送到可用的Web服务器上去.在穿过因特网的路径上,HTTP报文传输的方向会受到HTTP应用程序和报文经由的路由设备的影响: 配置创建客户端报文的浏览器应用 ...

  6. 「笔记」某移动SRE运维体系交流

    痛点 传统竖井式IT架构(封闭.隔离.非标.难运维) X86 服务器硬件稳定性不足 开源软件可靠性不足,且不可控 出了故障,被动救火救不完 转型 由此催生了转型升级的需求: 运维智能(SRE)的转型 ...

  7. HMS Core 3D流体仿真技术,打造移动端PC级流体动效

    移动设备硬件的高速发展,让游戏行业发生翻天覆地的变化,许多酷炫的游戏效果不再局限于电脑端,玩家在移动端就能享受到场景更逼真.画质更清晰.体验更流畅的游戏服务.但由于移动设备算力不足,为了实现真实感的水 ...

  8. C++进阶(智能指针)

    智能指针原理 C++程序设计中使用堆内存是非常频繁的操作,堆内存的申请和释放都由程序员自己管理.程序员自己管理堆内存可以提高了程序的效率,但是整体来说堆内存的管理是麻烦的,C++11中引入了智能指针的 ...

  9. [python] ​python-pinyin库

    python-pinyin库是一个汉字拼音转换工具,其主要功能有: 根据词组智能匹配最正确的拼音. 支持多音字. 简单的繁体支持, 注音支持. 支持多种不同拼音风格. 安装命令为:pip instal ...

  10. SQL Server登录初次提示状态码233,再次登录提示状态码18456

    解决方案: 1.使用windows方式登录数据库,修改安全性属性为SQL Server 和Windows身份验证模式 2.打开SQL Server配置管理器,启动MSSQLSERVER协议 3.修改s ...