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日

相关文章

  • SpringBoot详细介绍SPI机制示例

    SpringBoot详细介绍SPI机制示例 在SpringBoot中,我们可以使用SPI机制来扩展框架的功能。本文将详细讲解SpringBoot详细介绍SPI机制示例的完整攻略,并提供两个示例。 1. SPI机制 SPI全称为Service Provider Interface,是Java提供的一种服务发现机制。在SPI机制中,服务提供者提供一种服务接口,而…

    Java 2023年5月15日
    00
  • springboot 按月分表的实现方式

    下面是springboot按月分表的实现方式完整攻略: 第一步:创建表和初始化数据 首先,我们需要创建一张原始的订单表,结构如下: CREATE TABLE `order` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT ‘主键ID’, `order_no` varchar(64) DEFAULT NULL…

    Java 2023年5月20日
    00
  • Storm框架整合springboot的方法

    下面是详细的Storm框架整合Spring Boot的方法: 1. 在Spring Boot项目中添加Storm依赖 首先需要在Spring Boot项目的pom.xml中添加Storm的依赖。在<dependencies>标签内添加以下内容: <dependency> <groupId>org.apache.storm&…

    Java 2023年5月15日
    00
  • Java sha1散列算法原理及代码实例

    Java sha1散列算法原理及代码实例 前言 在软件开发场景中,我们经常会需要对敏感数据进行加密处理,以防止数据泄漏和恶意攻击。散列算法是一种很好的加密方式。本文将详细介绍Java中的sha1散列算法,包括原理及代码实例。 sha1散列算法原理 sha1散列算法是一种单向不可逆算法,通过该算法我们可以将任意长度的数据进行加密处理。在Java中,sha1散列…

    Java 2023年5月19日
    00
  • Java并发编程之创建线程

    当进行Java并发编程时,创建线程是其中非常重要的一个步骤。本篇攻略将为你详细介绍Java中创建线程的各种方式和技巧,并提供两条实际例子。 一、Java中创建线程的方式 Java中创建线程有以下几种方式: 1. 继承Thread类 此方法需要继承Java中的Thread类,并重写其run()方法来定义线程的行为。 public class MyThread …

    Java 2023年5月23日
    00
  • java如何用正则表达式匹配与提取字符串

    Java中使用正则表达式匹配和提取子字符串可以通过Java标准库中的Pattern和Matcher类实现。以下是使用正则表达式进行匹配和提取的攻略: 步骤1:创建正则表达式 首先需要创建一个正则表达式来匹配和提取字符串。正则表达式是由一些特殊字符和普通字符组成的模式,用于描述要匹配的字符串的形式。例如,正则表达式\d+ 可以匹配一个或多个数字。 步骤2:编译…

    Java 2023年5月27日
    00
  • Spring Data JPA 注解Entity关联关系使用详解

    Spring Data JPA 是 Spring Data 项目中处理 JPA 持久层的一种方法,它提供了很多注解和工具来简化 JPA 操作,其中 Entity 关联关系是 JPA 中的核心概念之一。本文将介绍 Spring Data JPA 中 Entity 关联关系的使用方法,主要包括关联关系的种类、注解的使用和案例演示。 关联关系种类 在 JPA 中,…

    Java 2023年6月3日
    00
  • JAVA实现Base64编码的三种方式

    JAVA实现Base64编码的三种方式 Base64是一种用64个字符来表示二进制数据的方法,通常用于在HTTP等情境下传递二进制数据。在JAVA中,我们可以通过以下三种方式来进行Base64编码的实现。 1. 使用Java 8提供的java.util.Base64类(推荐使用) Java 8 中增加了一个 Base64 类,用于提供一种标准的Base64编…

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