javascript中负数算术右移、逻辑右移的奥秘探索

在 JavaScript 中,右移运算符由三个大于号(),两个大于号() 和一个小于号()组成。右移运算符可以对二进制数进行运算,将其向右移动指定的位数。右移运算符在常见的开发中并不常用,但是在某些场景下会非常有用。

JavaScript中负数算术右移、逻辑右移的奥秘探索

1. 什么是右移运算符

在 JavaScript 中,右移运算符由三个大于号(>>>),两个大于号(>>) 和一个小于号(<<)组成。右移运算符可以对二进制数进行运算,将其向右移动指定的位数。右移运算符在常见的开发中并不常用,但是在某些场景下会非常有用。

1.1 算术右移运算符

算术右移运算符由两个大于号(>>)组成,与其它语言中的操作相似。算术右移会将数字的二进制形式整体向右移动并保留符号位(即正负号),被移出的位将会被舍弃。

例如,将 -12 进行算术右移动 2 位,我们可以得到:

-12 >> 2 // -3

在这个例子中,-12 的二进制形式为 11111111111111111111111111110100,向右移动两位后,变成了 11111111111111111111111111111101,根据补码的规则,我们可以得到 -3。

1.2 逻辑右移运算符

逻辑右移运算符由三个大于号(>>>)组成,与算术右移运算符基本相似,主要区别在于它不会保留符号位,而是在开头插入 0。

例如,将 -12 进行逻辑右移动 2 位,我们可以得到:

-12 >>> 2 // 1073741821

在这个例子中,-12 的二进制形式为 11111111111111111111111111110100,向右移动两位后,变成了 00111111111111111111111111111101,根据这个二进制数的值是 1073741821(其二进制形式为 00111111111111111111111111111101)。

2. 为什么存在算术右移和逻辑右移

JavaScript 中存在算术右移和逻辑右移,主要是为了满足不同场景的需求。

在大多数情况下,如果将负数进行右移操作,可能会导致程序运行异常或者逻辑上不正确。因此,在需要处理有符号整数时,应该尽量使用算术右移运算符。

而当处理无符号整数或二进制数时,无需考虑符号位,逻辑右移运算符可以更好地完成这些工作。

3. 示例说明

3.1 算术右移运算符示例

我们可以使用算术右移运算符将一个大于 32 位的数字进行截断:

let num = 1099511627776;
let truncated = num >> 32;
console.log(truncated); // 0

在这个例子中,1099511627776 的二进制形式为 1000000000000000000000000000000000000,即为 1 后面跟 40 个 0。整体右移 32 位后,仍然为 1 后面跟 8 个 0,等于 0。

3.2 逻辑右移运算符示例

我们可以使用逻辑右移运算符从一个数字的二进制表示获取其二进制值为 1 的位数:

function countTrailingZeros(num) {
  let trailingZeros = 0;
  while (num) {
    if (num & 1) {
      break;
    }
    num >>>= 1;
    trailingZeros++;
  }
  return trailingZeros;
}

console.log(countTrailingZeros(16)); // 4

在这个例子中,我们将一个数的二进制值向右移位并不断检查最后一位,如果是 1 的话,则停止移位,并返回移位的次数。在这个例子中,数字 16 的二进制值为 00000000000000000000000000010000,向右移动四位后,得到 00000000000000000000000000000001,此时函数停止移位并返回 4,代表原数字的二进制值有 4 个 0。

本文标题为:javascript中负数算术右移、逻辑右移的奥秘探索

基础教程推荐