js中的位运算执行效率更高,恰当地使用可以使代码更加优雅,性能更高。本文以零填充右移运算>>>为切入点,整理一下js位运算。
js中的位运算基于32位二进制数执行
js中数字是以64位浮点数
形式存储的,默认为十进制。在执行位运算之前,js将数字转换为32位有符号整数
,执行完位运算后,再将数值转换为64位十进制数字。
上图是js中执行位运算的大致流程,可以看到补码
是用于位运算的,位运算结束后的结果仍是补码
,需要转成原码表示数值
。
怎样求数字的二进制补码?
先来了解几个概念:
- 原码 如图所示最高位(蓝色)是符号位,0表示正数1表示负数。其他位(白色)表示数值。
- 反码
1)正数的反码
正数本身,即原码。
2)负数的反码
符号位不变,其余位取反。
3. 补码
求补码的方法:
1) 正数的补码是本身,即原码。
2) 负数的补码是负数的反码加1.
4.补码转原码
1) 补码为正数,原码是本身。
2) 补码为负数,原码是补码-1的反码.
零填充右移运算>>>
下面通过两个🌰理解一下>>>运算。
例1: 正数零填充右移
let num = 5;
// 转二进制
num.toString(2); // '101'
num = num >>> 1; // 2
num.toString(2); // '10'
5的二进制表示为101,执行5 >>> 1
,即将5的二进制表示右移1位,空出来的高位用0填充。
如图所示,5的补码是5,右移1位高位补0得到2,2转成原码还是2.
注意: 符号位
也参与了运算!
例2: 负数零填充右移
let num = -5;
// 转二进制
num.toString(2); // '-101'
num = num >>> 1; // 2147483645
num.toString(2); // '1111111111111111111111111111101'
如图所示,-5的二进制补码是11111111111111111111111111111011,右移1位高位补0得到01111111111111111111111111111101,由负数变成了正数,原码是正数本身,即2147483645。
由于右移后高位补0,所以零填充右移的结果恒为非负值。
总结
- js中会将数值转成对应的二进制补码,再执行位运算,运算结束后,将结果转换成原码表示数值。
- 零填充右移运算>>>,符号位也参与运算,零填充右移的结果恒为非负值。