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 00111000 0000 0000 0000 0000 0000 0000 0011
反码0000 0000 0000 0000 0000 0000 0000 00111111 1111 1111 1111 1111 1111 1111 1100
补码0000 0000 0000 0000 0000 0000 0000 00111111 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
    
  3. 非数值类型

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

    null >>> 0 		// 0
    function right () {}
    right >>> 0 	// 0
    
  4. 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
    
  2. 奇数偶数判断

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

    (x & 1) === 0	  // 偶数为true,奇数为false
    
  3. 交换两数值

    x ^= y
    y ^= x
    x ^= y
    
  4. 位移枚举(与传统枚举,可支持多选)

    举例,对于数据权限,通常包括增、删、改、查;某角色对某一数据权限,往往是一对多的过程(如只具备:增、查权限)

    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
    }
    
  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋飛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值