Codelet Keep code simple stupid

JavaScript位移操作

JavaScript语言中并没有真正的整数类型,number类型是浮点数,因此按位操作会首先将浮点数下取整, 转化为32位整数,运算完成后再转化为浮点数

JavaScript中一共有7种位操作符

  • 按位与 - &
  • 按位或 - |
  • 按位异或 - ^
  • 按位取反 - ~
  • 左移 - <<
  • 有符号右移 - >>
  • 无符号右移 - >>>

其中的按位右移有两种,分为有符号和无符号,这两者有什么区别呢?

先看正数

7 >> 1  // 3
7 >>> 1 // 3

结果是相等的,每右移1位相当于除以2

再看负数

-7 >> 1  // -4
-7 >>> 1 // 2147483644

负数无符号右移后得到了一个大正数,我们下面将数字 -7 按位展开

  -7
|31 30 ... 4 3 2 1 0|
  1  1 ... 1 1 0 0 1

  -7 >> 1
|31 30 ... 4 3 2 1 0|
  1  1 ... 1 1 1 0 0
  = -1 - 3
  = -4

  -7 >>> 1
|31 30 ... 4 3 2 1 0|
  0  1 ... 1 1 1 0 0
  = -1 - 3 - (-2^31)
  = 2147483644

所以,对于负数

  • 有符号右移操作,左边移入的bit填充1
  • 无符号右移操作,左边移入的bit填充0

JavaScript的位操作实际上和Java保持了一致,因为不支持unsigned整数类型,导致最高位等于1的整数 会被表示为负数,而负数的无符号右移和除以2并不能做等价,所以就引入了有符号右移,用来保持等价性, 所以有符号右移又称作算数右移(arithmetic shift),无符号右移又称作逻辑右移(logical shift)

参考资料:
[1] MDN - Bitwise Operators