右移 (>>)
右移 (>>) 运算符返回一个数字或 BigInt,其二进制表示是第一个操作数向右移动指定位数的结果。超出右侧的位被丢弃,并且最左侧的位副本从左侧移入。此操作也称为“符号传播右移”或“算术右移”,因为结果数字的符号与第一个操作数的符号相同。
试一试
const a = 5; // 00000000000000000000000000000101
const b = 2; // 00000000000000000000000000000010
const c = -5; // 11111111111111111111111111111011
console.log(a >> b); // 00000000000000000000000000000001
// Expected output: 1
console.log(c >> b); // 11111111111111111111111111111110
// Expected output: -2
语法
x >> y
描述
>> 运算符针对两种类型的操作数进行了重载:数字和 BigInt。对于数字,该运算符返回一个 32 位整数。对于 BigInt,该运算符返回一个 BigInt。它首先 将两个操作数强制转换为数值,然后测试它们的类型。如果两个操作数都变为 BigInt,则执行 BigInt 右移;否则,它将两个操作数转换为 32 位整数并执行数字右移。如果一个操作数变为 BigInt 而另一个变为数字,则会抛出 TypeError。
由于新的最左位与之前的最左位值相同,因此符号位(最左位)不会改变。因此得名“符号传播”。
该运算符作用于左操作数的 补码 二进制表示。考虑十进制(基数 10)数字 9 和 -9 的 32 位二进制表示:
9 (base 10): 00000000000000000000000000001001 (base 2)
-9 (base 10): 11111111111111111111111111110111 (base 2)
负十进制(基数 10)数字 -9 的补码二进制表示是通过反转其相反数(即 9,二进制为 00000000000000000000000000001001)的所有位,然后加 1 形成的。
在两种情况下,二进制数的符号都由其最左位给出:对于正十进制数 9,二进制表示的最左位是 0;对于负十进制数 -9,二进制表示的最左位是 1。
给定十进制(基数 10)数字 9 和 -9 的这些二进制表示:
9 >> 2 得到 2
9 (base 10): 00000000000000000000000000001001 (base 2)
--------------------------------
9 >> 2 (base 10): 00000000000000000000000000000010 (base 2) = 2 (base 10)
请注意,两个最右边的位 01 已被移出,并且两个最左边的位 0 的副本已从左侧移入。
-9 >> 2 得到 -3
-9 (base 10): 11111111111111111111111111110111 (base 2)
--------------------------------
-9 >> 2 (base 10): 11111111111111111111111111111101 (base 2) = -3 (base 10)
请注意,两个最右边的位 11 已被移出。但就最左边的位而言:在这种情况下,最左边的位是 1。因此,两个最左边的 1 位的副本已从左侧移入——这保留了负号。
二进制表示 11111111111111111111111111111101 等于负十进制(基数 10)数字 -3,因为所有负整数都存储为 补码,并且可以通过反转正十进制(基数 10)数字 3 的二进制表示(即 00000000000000000000000000000011)的所有位,然后加一来计算。
如果左操作数是超过 32 位的数字,则其最高有效位将被丢弃。例如,以下超过 32 位的整数将转换为 32 位整数:
Before: 11100110111110100000000000000110000000000001 After: 10100000000000000110000000000001
右操作数将转换为无符号 32 位整数,然后取模 32,因此实际的移位偏移量将始终是一个介于 0 到 31 之间(包括 0 和 31)的正整数。例如,100 >> 32 与 100 >> 0 相同(并产生 100),因为 32 模 32 是 0。
警告:您可能会看到有人使用 >> 0 将数字截断为整数。将任何数字 x 右移 0 会返回 x 转换为 32 位整数的结果,这还会移除超出 -2147483648 到 2147483647 范围的数字的前导位。请改用 Math.trunc()。
对于 BigInt,没有截断。从概念上讲,将正 BigInt 理解为具有无限数量的前导 0 位,将负 BigInt 理解为具有无限数量的前导 1 位。
示例
使用右移
9 >> 2; // 2
-9 >> 2; // -3
9n >> 2n; // 2n
规范
| 规范 |
|---|
| ECMAScript® 2026 语言规范 # sec-signed-right-shift-operator |
浏览器兼容性
加载中…