右移(>>)

右移运算符>>)将一个操作数的二进制表示形式向右移动指定位数,该操作数可以是数值或者 BigInt 类型。右边移出位被丢弃,左边移出的空位补符号位(最左边那位)。该操作也称为“符号位传播右移”(sign-propagating right shift)或“算术右移”(arithmetic right shift),因为返回值的符号位与第一个操作数的符号位相同。

尝试一下

语法

js
x >> y

描述

>> 运算符针对这两种操作数的类型进行了重载:数值和 BigInt。对于数值,该运算符返回一个 32 位整数;对于 BigInt 类型,该运算符返回一个 BigInt。右移运算符首先将两个操作数强制转换为数值并测试它们的类型。如果两个操作数都转换成 BigInt,则执行 BigInt 右移;否则,它将两个操作数都转换为 32 位整数并执行数值右移。如果一个操作数变为 BigInt 而另一个变为数值,则会抛出 TypeError

由于新的数字最左边位与之前数字的最左边位是相同值,故符号位(最左边的位)不会改变,因此被称为“符号位传播”(sign-propagating)。

运算符以二进制补码的形式对左操作数进行运算。考虑十进制(以 10 为底)数字 9-932 位二进制表示:

js
     9 (十进制): 00000000000000000000000000001001 (二进制)
    -9 (十进制): 11111111111111111111111111110111 (二进制)

十进制(以 10 为底)负数 -9 的二进制补码表示是将其相反数(即 9)的二进制表示 00000000000000000000000000001001 的所有位取反,再加 1

这两个数的二进制表示的符号位由其最左边的位决定:对于十进制正数 9,二进制表示的最左边位为 0,对于十进制负数 -9,二进制表示的最左边位是 1

给定十进制(以 10 为底)数 9-9 的二进制表示:

9 >> 2 得到 2

js
     9 (十进制): 00000000000000000000000000001001 (二进制)
                  --------------------------------
9 >> 2 (十进制): 00000000000000000000000000000010 (二进制) = 2 (十进制)

请注意最右边的 01 是如何移出的,最左边的 00 是如何从左边移入的。

-9 >> 2 得到 -3

js
     -9 (十进制): 11111111111111111111111111110111 (二进制)
                   --------------------------------
-9 >> 2 (十进制): 11111111111111111111111111111101 (二进制) = -3 (十进制)

请注意最右边的 11 是如何移出的。但最左边的位情况稍有不同:由于 -9 是负数,它的符号位(即最左边的位)是 1,因此右移 2 位时会在最左边补上 11,这便保留了负号。

二进制表示 11111111111111111111111111111101 等于十进制(以 10 为底)负数 -3,因为所有负整数都以二进制补码的形式存储,而 -3 的二进制补码可以通过将十进制(以 10 为底)正数 3 的二进制表示(即 00000000000000000000000000000011)的所有位先取反,然后加 1

如果左操作数是一个超过 32 位的数字,则会丢弃最高有效位。例如,以下超过 32 位的整数将被转换为 32 位整数:

丢弃前:11100110111110100000000000000110000000000001
丢弃后:            10100000000000000110000000000001

右操作数将被转换为无符号 32 位整数,然后取模 32,因此实际移位偏移量将始终是 0 到 31 之间的正整数,包括 0 和 31。例如,100 >> 32100 >> 0 相同(结果都是 100),因为 32 模 32 为 0。

BigInt 在使用右移时不会产生截断现象。从概念上讲,正 BigInt 具有无限数量的前导位 0,而负 BigInt 具有无限数量的前导位 1

将任何数字 x 右移 0 可以将 x 转换为 32 位整数。不要使用 >> 0 将数字截断为整数;使用 Math.trunc() 代替。

示例

使用右移操作

js
9 >> 2; //  2
-9 >> 2; // -3

9n >> 2n; // 2n

规范

Specification
ECMAScript Language Specification
# sec-signed-right-shift-operator

浏览器兼容性

BCD tables only load in the browser

参见