翼度科技»论坛 编程开发 JavaScript 查看内容

js 操作符 —— 位操作符详解

9

主题

9

帖子

27

积分

新手上路

Rank: 1

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


位运算符是在数字底层(即表示数字的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。
  1. 基于上述步骤确定-18 的二进制表示,首先从 18 的二进制表示开始
  2. 0000 0000 0000 0000 0000 0000 0001 0010
  3. 然后,计算一补数,即反转每一位的二进制值:
  4. 1111 1111 1111 1111 1111 1111 1110 1101
  5. 最后,给一补数加 1:
  6. 1111 1111 1111 1111 1111 1111 1110 1101
  7.                                       1
  8. ---------------------------------------
  9. 1111 1111 1111 1111 1111 1111 1110 1110
复制代码
所以,-18 的二进制表示就是 11111111111111111111111111101110。


1. 按位非(~)
(~)是返回数值的一补数。
  1. let num1 = 25;      // 二进制 00000000000000000000000000011001
  2. let num2 = ~num1;   // 二进制 11111111111111111111111111100110
  3. console.log(num2);  // -26
复制代码
可以看出,(~)可以当做是这个数的绝对值取反减1的二进制数;
*** 小技巧: 对一个小数两次按位非,可以得到取整效果。
  1. console.log(~~2.5); // 2
复制代码

2. 按位与(&)
按位与操作符用和号(&)表示,有两个操作数。本质上,按位与就是将两个数的每一个位对齐,然后基于真值表中的规则,对每一位执行相应的与操作。
tips: 是转化成二进制的对应位数下的值是否一致;

  1. let result = 25 & 3;
  2. console.log(result); // 1
  3. 25 和 3 的按位与操作的结果是 1。为什么呢?看下面的二进制计算过程:
  4. 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  5. 3 = 0000 0000 0000 0000 0000 0000 0000 0011
  6. ---------------------------------------------
  7. & = 0000 0000 0000 0000 0000 0000 0000 0001
  8. 如上所示,25 和 3 的二进制表示中,只有第 0 位上的两个数都是 1。于是结果数值的所有其他位都会以 0 填充,因此结果就是 1。
复制代码
*** 小技巧:和1进行按位&操作来判断其奇偶性,比如 num&1,若为1,则num是奇数;若为0,则num是偶数。
3. 按位或(|)
按位或操作符用管道符(|)表示,同样有两个操作数。按位或操作在至少一位是 1 时返回 1,两位都是 0 时返回 0。

  1. let result = 25 | 3;
  2. console.log(result); // 27
  3. 可见 25 和 3 的按位或操作的结果是 27:
  4. 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  5.   3 = 0000 0000 0000 0000 0000 0000 0000 0011
  6. ---------------------------------------------
  7. | = 0000 0000 0000 0000 0000 0000 0001 1011
  8. 在参与计算的两个数中,有 4 位都是 1,因此它们直接对应到结果上。二进制码 11011 等于 27。
复制代码
4. 按位异或(^)
按位异或用脱字符(^)表示,同样有两个操作数。
按位异或与按位或的区别是,它只在一位上是 1 的时候返回 1(两位都是 1 或 0,则返回 0)。

  1. let result = 25 ^ 3;
  2. console.log(result); // 26
  3. 可见,25 和 3 的按位异或操作结果为 26,如下所示:
  4. 25 = 0000 0000 0000 0000 0000 0000 0001 1001
  5.   3 = 0000 0000 0000 0000 0000 0000 0000 0011
  6. ---------------------------------------------
  7.   ^ = 0000 0000 0000 0000 0000 0000 0001 1010
  8. 两个数在 4 位上都是 1,但两个数的第 0 位都是 1,因此那一位在结果中就变成了 0。其余位上的 1
  9. 在另一个数上没有对应的 1,因此会直接传递到结果中。二进制码 11010 等于 26。
复制代码
  
5. 左移()表示,会将数值的所有 32 位都向右移,同时保留符号(正或负)。有符号右移实际上是左移的逆运算。比如,如果将 64 右移 5 位,那就是 2。


 
 7. 无符号右移(>>>)
无符号右移用 3 个大于号表示(>>>),会将数值的所有 32 位都向右移。
对于正数:无符号右移与有符号右移结果相同。仍然以前面有符号右移的例子为例,64 向右移动 5 位,会变成 2。
对于负数:因为负数是其绝对值的二补数,所以右移之后结果变得非常之大。
  1. let num= -64; // 等于二进制 11111111111111111111111111000000
  2. let result = num >>> 5; // 等于十进制 134217726
复制代码
 小技巧:
使用两个叹号(!!),相当于调用了转型函数Boolean()。
指数操作符(**):ECMAScript 7 新增了指数操作符,Math.pow()现在有了自己的操作符**
  1. ##  双非 !!
  2. console.log(!!"blue"); // true
  3. console.log(!!0); // false
  4. console.log(!!NaN); // false
  5. console.log(!!""); // false
  6. console.log(!!12345); // true
  7. ##  指数操作符**
  8. Math.pow(3, 2); // 3的平方: 9
  9. 3 ** 2; // 3的平方: 9
  10. 3 ** 3; // 3的三次方: 27
复制代码
  

来源:https://www.cnblogs.com/leng12/p/17172055.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具