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中负数算术右移、逻辑右移的奥秘探索 - Python技术站

(0)
上一篇 2023年6月15日
下一篇 2023年6月15日

相关文章

  • Maven 生成打包可执行jar包的方法步骤

    Maven 是一款优秀的项目管理工具,也是开发 Java 项目的标准工具之一,本文将介绍使用 Maven 生成打包可执行 jar 包的方法步骤,具体如下: 步骤一:创建 Maven 项目 在开始之前,先要确保安装了 JDK 和 Maven,然后执行以下命令: mvn archetype:generate -DgroupId=com.mycompany.app…

    Java 2023年5月26日
    00
  • 谈谈JavaScript自定义回调函数

    谈谈JavaScript自定义回调函数 什么是回调函数? 回调函数是一种特殊的函数,它作为参数传递给另一个函数并且在主函数执行完成后被调用。通常情况下,回调函数用于处理异步操作。比如,当一个网络请求完成时,需要回调函数来处理返回的数据。 JavaScript自定义回调函数的基本用法 在JavaScript中,我们可以通过自定义函数来实现回调函数的功能。下面是…

    Java 2023年6月15日
    00
  • JAVA 时间区间的字符串合法性验证

    下面是“JAVA 时间区间的字符串合法性验证”的完整攻略: 背景 在Java中,时间区间通常由一个开始时间和一个结束时间组成,比如“2019-01-01 00:00:00”到“2019-01-01 23:59:59”这样的字符串格式。在实际开发中,我们需要对时间区间的字符串格式进行合法性验证,保证输入数据的有效性。本文将介绍一种简单有效的JAVA时间区间字符…

    Java 2023年5月20日
    00
  • Spring整合MyBatis的三种方式

    Spring整合MyBatis的三种方式 在使用Spring整合MyBatis时,有三种常见的方式: 方式一:使用注解配置 方式二:使用XML配置 方式三:使用Java配置 接下来,将分别对这三种方式进行详细讲解。 方式一:使用注解配置 使用注解配置整合MyBatis非常简单,只需要在Spring配置文件中添加以下代码: <!– 配置MyBatis扫…

    Java 2023年5月19日
    00
  • Java中构造方法set/get和toString的使用详解

    “Java中构造方法set/get和toString的使用详解”即是一篇文章,下面是这篇文章的完整攻略。 Java中构造方法set/get和toString的使用详解 构造方法 在Java中,构造方法是用于创建对象时进行初始化的方法,其名称必须与名称相同。 public class Person { private String name; private …

    Java 2023年5月26日
    00
  • Java Scanner对象中hasNext()与next()方法的使用

    Java Scanner对象是一个用于从输入流中获取用户输入信息的类。其中,hasNext()和next()是Scanner类中常用的方法,用于读取输入流中的下一个token(以空格、tab、换行符为分隔符),并检测输入流是否还有下一个token。 hasNext()方法的使用 hasNext()方法用于检测输入流是否还有下一个token。其语法如下: pu…

    Java 2023年5月26日
    00
  • 深入理解Java中的克隆

    深入理解Java中的克隆攻略 在Java中,对象的克隆可分为浅拷贝和深拷贝两类,深拷贝是创建一个新的对象,将原始对象所有的属性都复制到新对象中,新对象与原始对象互不干扰;浅拷贝则是创建一个新的对象,但是将原始对象中的基本类型的值和引用类型的指针都复制到新对象中,两者共享引用类型的数据,修改其中一个对象会影响另外一个对象。 对象的克隆方式 Java中对象的克隆…

    Java 2023年5月26日
    00
  • Java 数据结构与算法系列精讲之红黑树

    红黑树 简介 红黑树是一种自平衡二叉搜索树,它是被广泛使用的一种数据结构,在计算机领域中用于实现高效的查找、插入和删除操作。其名字的由来是因为每个节点都有一个被标记为红色或黑色的属性,又因为它是二叉搜索树,因此在插入、删除操作后,它会自动调整以保持平衡状态。 红黑树的定义 红黑树最重要的两个属性是: 每个节点或者是黑色,或者是红色。 根节点是黑色。 每个叶节…

    Java 2023年5月26日
    00
合作推广
合作推广
分享本页
返回顶部