0
点赞
收藏
分享

微信扫一扫

javascript 位操作用途、位移枚举(多选枚举)


计算机系统中,数值一律采用补码来表示和存储(寄存器)。
javascript 中所有数字均用浮点数值表示,采用 IEEE 754 标准定义的 64 位浮点格式表示数字。

javascript 中实际的操作(数组索引以及位操作符)都是基于 32 位整数(有符号)。操作完成之后,再按照 64 位浮点数存储。

~~212121212121123=1367306275

原数:212121212121123

转二进制 ​​toString(2)​​:110000001110110001010001011111110111000000100011

JS 32位(舍掉超出位数):01010001011111110111000000100011

​~~​​ 执行之后:01010001011111110111000000100011

转十进制 ​​parseInt('', 2)​​:1367306275

javascript 中的整型在内存中都是一个 64 位双精度浮点型,但是 js 进行位运算时,会将操作数转成带符号位的 32 位比特序列 ​​01​​(补码)。运算结束后,再按照 64 位浮点格式存储。这样导致的结果:精度丢失(直接截断)!

按位运算符

注意: 所有操作都是基于计算机存储的补码进行操作的。

正数(3)

负数(-3)

原码

0000 0000 0000 0000 0000 0000 0000 0011

1000 0000 0000 0000 0000 0000 0000 0011

反码

0000 0000 0000 0000 0000 0000 0000 0011

1111 1111 1111 1111 1111 1111 1111 1100

补码

0000 0000 0000 0000 0000 0000 0000 0011

1111 1111 1111 1111 1111 1111 1111 1101

  • 正数:原码、反码、补码一致
  • 负数:反码,符号位不变,其他位取反;补码,反码基础+1

运算符

3 [opt] -3

&(AND)

0000 0000 0000 0000 0000 0000 0000 0001(1)

|(OR)

1111 1111 1111 1111 1111 1111 1111 1111 (-1)

^(XOR)

1111 1111 1111 1111 1111 1111 1111 1110(-2)

移位操作

运算符

说明

左移 ​​a << b​

将第一个操作数向左移动指定位数,左边超出的位数将会被清除,右边将会补零

右移 ​​a >> b​

将第一个操作数右移指定的位数。右移的多余位被丢弃。符号位不变。

无符号右移 ​​a >>> b​

将第一个操作数右移指定的位数。右移的多余位被丢弃。左边将会补零(结果始终为非负

注意: 移位运算符在 CPU 中的运算器进行操作的,采用补码

a = -5  // 11111111111111111111111111111011
a >> 2 // 11111111111111111111111111111110 => 10000000000000000000000000000010
a >>> 2 // 00111111111111111111111111111110

关于位数超出:​​setTimeout/setInterval delay数值过大问题​​

说明

  1. javascript中浮点数也能参与运算
    javascript 中实际的操作(数组索引以及位操作符)都是基于 32 位整数(补码)。操作完成之后,再按照 64 位浮点数存储。
  2. 小数部分,全部舍弃

~~1.1   // 1
~~-2.2 // -2

  1. 非数值类型
    首先将操作数转成一个整型(就是0),然后进行运算

null >>> 0     // 0
function right () {}
right >>> 0 // 0

  1. javascript 中无符号右移 ​​>>>​​ 特别之处

-1 >>> 0     // 4294967295

原码:10000000 00000000 00000000 00000001
补码:11111111 11111111 11111111 11111111
右移:11111111 11111111 11111111 11111111 // 无符号

注意:与其它按位运算符不同,无符号右移返回无符号 32 位整数。

用途

  1. 清零
    任何数与0做运算结果都是0

123123 & 0    // 0
-12312 & 0 // 0

  1. 奇数偶数判断
    二进制的末尾是0则是偶数,为1则是奇数

(x & 1) === 0   // 偶数为true,奇数为false

  1. 交换两数值

x ^= y
y ^= x
x ^= y

  1. 位移枚举(与传统枚举,可支持多选)
    举例,对于数据权限,通常包括增、删、改、查;某角色对某一数据权限,往往是一对多的过程(如只具备:增、查权限)

const Permission = {
None: 0, // 0000 0
Get: 1 << 0, // 0001 1
Post: 1 << 1, // 0010 2
Put: 1 << 2, // 0100 4
Delete: 1 << 3 // 1000 8
}

获取是否具有权限

function resolvePermission (payload) {
return {
Get: !!(payload & Permission.Get),
Post: !!(payload & Permission.Post),
Put: !!(payload & Permission.Put),
Delete: !!(payload & Permission.Delete)
}
}

resolvePermission(3) // {Get: true, Post: true, Put: false, Delete: false}
resolvePermission(15) // {Get: true, Post: true, Put: true, Delete: true}

延伸1:查找给定数字num的特定位置​i​

function getBit (num, i) {
return ((num & (1 << i)) !== 0)
}

getBit(5, 0) // true
getBit(5, 1) // false
getBit(5, 2) // true

延伸2:给定数字num的特定位置​i​设置位

function setBit (num, i) {
return num | (1 << i)
}

延伸3:清除给定数字num的特定位置​i​处的位

function clearBit (num, i) {
let mask = ~(1 << i)
return num & mask
}


举报

相关推荐

0 条评论