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

yizhihongxing

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日

相关文章

  • SpringBoot Security密码加盐实例

    下面是关于 “SpringBoot Security密码加盐实例” 的详细攻略。 介绍 Spring Security 是一个强大的身份认证和授权框架,Spring Boot 的集成让我们可以非常方便地搭建安全的应用。但是,如果我们对密码进行单纯的 hash 加密,容易被暴力破解,因此需要加盐(salt)使其更加安全。 盐是在密码加密的时候添加到原始密码中的…

    Java 2023年6月3日
    00
  • Java 跳出递归循环问题解决办法

    Java 跳出递归循环问题通常出现在递归函数内部的某一个条件不满足时,需要跳出递归循环。 常见的解决办法有以下几种: 使用非递归实现 将递归函数转换成非递归的形式,使用栈或队列进行迭代实现。这样的好处是可以在循环中使用break或return语句来跳出循环。 示例1:阶乘的非递归实现 public static long factorial(int n) {…

    Java 2023年5月25日
    00
  • 几道和「黑洞照片」那种海量数据有关的算法问题

    这个话题涉及到海量数据处理和算法问题,我会尽可能详细地解释来帮助大家了解。 大数据处理的常用算法 排序算法 排序是大数据处理中最常用的算法之一。这是因为,在许多情况下,我们需要对从数据库中获取的大量数据进行排序,以便更好地分析和使用它们。以下是一些常用的排序算法: 冒泡排序:这是一种简单的排序算法,在较小的数据集中表现良好,但对于大规模数据集则效率较低。 快…

    Java 2023年5月19日
    00
  • 集成apollo动态日志取缔logback-spring.xml配置

    当我们使用Spring Boot构建应用程序时,Logback是默认的日志框架。然而,有些使用者更喜欢使用apollo,所以这里介绍如何在集成apollo后使用其动态日志管理功能代替Logback。 1. 添加apollo客户端依赖 首先要将如下依赖添加到应用程序的pom.xml文件中: <dependency> <groupId>c…

    Java 2023年5月20日
    00
  • jdbc连接数据库实例详解

    JDBC连接数据库实例详解 在Java程序中,经常需要与数据库进行交互。JDBC(Java Database Connectivity)是Java开发中用于连接和操作数据库的标准API。本文将详细介绍JDBC连接数据库的相关知识,包括JDBC连接步骤、示例代码等。 JDBC连接步骤 JDBC连接数据库的基本步骤如下: 加载数据库驱动 连接数据库 创建Stat…

    Java 2023年5月19日
    00
  • 【SSM】一、了解Sping 框架

    〇、Maven 0.1 什么是Maven? Apache Maven is a software project management and comprehension tool. Based on the concept of a project object model (POM), Maven can manage a project’s build…

    Java 2023年4月25日
    00
  • Lombok基本注解之@SneakyThrows的作用

    下面是关于Lombok基本注解之@SneakyThrows的作用的完整攻略。 1. @SneakyThrows简介 在Java中,我们通常使用try-catch语句捕获异常。但是,有时候代码中出现的异常并不是我们想要处理的,而是完全出乎意料的异常情况,这时候需要抛出异常。抛出异常通常要求在方法签名上声明当前方法可能会抛出某种类型的异常,这会使代码变得冗长,甚…

    Java 2023年5月26日
    00
  • java 操作windows 共享目录方法介绍

    Java操作Windows共享目录方法介绍 Java是一种跨平台的编程语言,但在处理Windows操作系统上的共享文件和目录时,需要遵循特定的步骤。本文介绍Java操作Windows共享目录的方法,旨在帮助开发人员在处理共享目录时更加安全和高效地进行开发。 1. Windows共享路径的格式 在Java中,我们需要了解Windows共享路径的格式,以便正确访…

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