js位移运算符~和>>>

位运算符有 7 个,分为两类:
逻辑位运算符:位与(&)、位或(|)、位异或(^)、非位(~)
移位运算符:左移(<<)、右移(>>)、无符号右移(>>>)

左位移&右位移

“<<”运算符执行左移位运算。
在移位运算过程中,符号位始终保持不变。如果右侧空出位置,则自动填充为 0;超出 32 位的值,则自动丢弃。

“>>”运算符执行有符号右移位运算。
它把 32 位数字中的所有有效位整体右移,再使用符号位的值填充空位。移动过程中超出的值将被丢弃。

>>>无符号右移

运算符执行五符号右移位运算。
它把无符号的 32 位整数所有数位整体右移。
对于无符号数或正数右移运算,无符号右移与有符号右移运算的结果是相同的。

~位非运算符

用于对一个二进制操作数逐位进行取反操作。
第 1 步:把运算数转换为 32 位的二进制整数。
第 2 步:逐位进行取反操作。
第 3 步:把二进制反码转换为十进制浮点数。

小数部分直接丢弃

运用:比如计算时间戳转为多少时分秒前,计算流量TGM,这时候需要每层取整。

  1. 数字取整
  ~~2.2 // 2 取反去掉了小数但符号是负数,再次取反为正。
  ~~2.8 // 2
  2.2>>0 // 2
  2.8>>0 // 2 写法比~~好,直接位操作,不用位运算两次
  2.2<<0 // 2
  2.8<<0 // 2
  1. 除数取整
1 >> 1 // 0 1/2 = 0
2 >> 1 // 1 2/2 = 1
3 >> 1 // 1 3/2 = 1
4 >> 1 // 2 4/2 = 2
5 >> 1 // 2 5/2 = 2
6 >> 1 // 3 6/2 = 3
7 >> 1 // 3 7/2 = 3
8 >> 1 // 4 8/2 = 4

公式: n >> x => n / x => parseInt( n / x ^ 2 )

n除于x的2次方取整。x表示位移几个位置,在二进制中,一位是2的平方,n位即是2的n次方.

  1. 乘于2的x次方
3 << 3 // 3 * 2 ^ 3 == 24

公式: n << x => n * 2 ^ x

非数值类型

非数值位运算时,会将操作值转为整型(就是0)。
而整型在内存中是64位双精度存储,位运算时会被转为32位。
在js中,超过32是直接截掉处理的。
位运算结束后又转为62位,这时候会丢失精度。
所以对非数值位运算,实际是对0取反,得到一定是-1

  ~非数值 // -1

判断是否是数字

let a = '1'
let b = 1
!isNan(a) // false
!isNan(b) // true
!!~~a // false
!!~~b // true
~a === -1 // true
~b === -1 // false

对负数

无论正负数,都会先执行符号位补0,再位移。
无符号右移将使用 0 来填充所有的空位,同时会把负数作为正数来处理。
所以负数永远得到一个很大的值。
永远返回正整数

  -1 >>> 0 // 4294967295

运用技巧

操作数组
let arr = [1,2,3]
arr.splice(arr.indexOf(3) >>> 0, 1) // 获取数组中的某个值

使用无符号右移来判断下标是否存在,存在则切割该值返回切割后的数组,否则返回空数组。
如果不使用位移操作,会返回-1,得到的是数组的最后一个值,splice(-1, 1) 会从后面进行查找切割。
将判断和查找合在一起写,简化程序。

!~位反位移然后取反

隐藏哨位,内置函数的值暴露出来称为暴露哨位。

// 一般这么判断
if ('abc'.indexOf('a') === -1) // 找不到则...
// 改成方便我们直接用来判断的方式
if (!~'abc'.indexOf('a')) // 通过位移到0,取反则是找不到,不用判断等于-1
// 现在基本使用es6的include
if ('abc'.includes('a'))
//等同
if (!!~'abc'.indexOf('a')) // 找不到取反
其他:
  1. 双位反取整
  2. 除数取整
  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值