【JavaScript】JavaScript位操作符

JavaScript位操作符

位操作符用于在最基本的层次上,即按内存中表示数值的位来操作数值。ECMAScript 中的所有数值都以 IEEE-754 64 位格式存储,但位操作符并不直接操作 64 位的值。而是先将 64 位的值转换成 32 位的整数,然后执行操作,最后再将结果转换回 64 位。对于开发人员来说,由于 64 位存储格式是透明的,因此整个过程就像是只存在 32 位的整数一样。

对于有符号的整数,32 位中的前 31 位用于表示整数的值。第 32 位用于表示数值的符号:0 表示正数,1 表示负数。这个表示符号的位叫做符号位,符号位的值决定了其他位数值的格式。其中,正数以纯二进制格式存储,31 位中的每一位都表示 2 的幂。第一位(叫做位 0)表示 20,第二位表示 21

,以此类推。没有用到的位以 0 填充,即忽略不计。例如,数值 18 的二进制表示是00000000000000000000000000010010,或者更简洁的 10010。这是 5 个有效位,这 5 位本身就决定了实际的值(如图)

负数同样以二进制码存储,但使用的格式是二进制补码。计算一个数值的二进制补码,需要经过下列 3 个步骤:

(1) 求这个数值绝对值的二进制码(例如,要求?18 的二进制补码,先求 18 的二进制码);
(2) 求二进制反码,即将 0 替换为 1,将 1 替换为 0;
(3) 得到的二进制反码加 1。
要根据这 3 个步骤求得-18 的二进制码,首先就要求得 18 的二进制码,即:
0000 0000 0000 0000 0000 0000 0001 0010
然后,求其二进制反码,即 0 和 1 互换:
1111 1111 1111 1111 1111 1111 1110 1101
最后,二进制反码加 1:
1111 1111 1111 1111 1111 1111 1110 1101
 		                                                        1
------------------------------------------------------
1111 1111 1111 1111 1111 1111 1110 1110
这样,就求得了-18 的二进制表示,即 11111111111111111111111111101110。要注意的是,在处理有
符号整数时,是不能访问位 31 的。

在 ECMAScript 中,当对数值应用位操作符时,后台会发生如下转换过程:64 位的数值被转换成 32位数值,然后执行位操作,最后再将 32 位的结果转换回 64 位数值。这样,表面上看起来就好像是在操作 32 位数值,就跟在其他语言中以类似方式执行二进制操作一样。但这个转换过程也导致了一个严重的副效应,即在对特殊的 NaN 和 Infinity 值应用位操作时,这两个值都会被当成 0 来处理。如果对非数值应用位操作符,会先使用 Number()函数将该值转换为一个数值(自动完成),然后再应用位操作。得到的结果将是一个数值。下面列出JavaScript中的几个位操作符

一、按位非( ~ )

按位非操作的本质:操作数的负值减 1。

var num1 = 25;    // 二进制 00000000000000000000000000011001
var num2 = ~num1; // 二进制 11111111111111111111111111100110
console.log(num2); // -26
var num1 = 25;
var num2 = -num1 - 1;
console.log(num2); // -26

虽然以上代码也能返回同样的结果,但由于按位非是在数值表示的最底层执行操作,因此速度更快。

二、按位与( & )

按位与操作只在两个数值的对应位都是 1 时才返回 1,任何一位是 0,结果都是 0

var result = 25 & 3;
console.log(result); //1

25 和 3 的二进制码对应位上只有一位同时是 1,而其他位的结果自然都是 0,因此最终结果等于 1。

三、按位或( | )

按位或操作在有一个位是 1 的情况下就返回 1,而只有在两个位都是 0 的情况下才返回 0。

var result = 25 | 3;
console.log(result); //27

这两个数值的都包含 4 个 1,因此可以把每个 1 直接放到结果中。二进制码 11011 等于十进制值 27。

四、按位异或( ^ )

按位异或与按位或的不同之处在于,这个操作在两个数值对应位上只有一个 1 时才返回 1,如果对应的两位都是 1 或都是 0,则返回 0。

var result = 25 ^ 3;
console.log(result); //26

这两个数值都包含 4 个 1,但第一位上则都是 1,因此结果的第一位变成了 0。而其他位上的 1 在另一个数值中都没有对应的 1,可以直接放到结果中。二进制码 11010 等于十进制值 26(注意这个结果比执行按位或时小 1)。

五、左移( << )

此操作符会将数值的所有位向左移动指定的位数。

var oldValue = 2; // 等于二进制的 10
var newValue = oldValue << 5; // 等于二进制的 1000000,十进制的 64

在向左移位后,原数值的右侧多出了 5 个空位。左移操作会以 0 来填充这些空位,以便得到的结果是一个完整的 32 位二进制数,左移不会影响操作数的符号位。换句话说,如果将?2 向左移动 5 位,结果将是-64,而非 64。

六、有符号右移( >> )

这个操作符会将数值向右移动,但保留符号位(即正负号标记)。有符号的右移操作与左移操作恰好相反

var oldValue = 64; // 等于二进制的 1000000
var newValue = oldValue >> 5; // 等于二进制的 10 ,即十进制的 2

同样,在移位过程中,原数值中也会出现空位。只不过这次的空位出现在原数值的左侧、符号位的右侧。而此时 ECMAScript 会用符号位的值来填充所有空位,以便得到一个完整的值。

七、无符号右移( >>> )

这个操作符会将数值的所有 32 位都向右移动。对正数来说,无符号右移的结果与有符号右移相同;但是对负数来说,情况就不一样了。首先,无符号右移是以 0 来填充空位,而不是像有符号右移那样以符号位的值来填充空位。所以,对正数的无符号右移与有符号右移结果相同,但对负数的结果就不一样了。其次,无符号右移操作符会把负数的二进制码当成正数的二进制码。而且,由于负数以其绝对值的二进制补码形式表示,因此就会导致无符号右移后的结果非常之大

var oldValue = -64; // 等于二进制的 11111111111111111111111111000000
var newValue = oldValue >>> 5; // 等于十进制的 134217726

当对-64 执行无符号右移 5 位的操作后,得到的结果是 134217726。之所以结果如此之大,是因为无符号右移操作会把这个数的二进制码当成正数的二进制码,换算成十进制就是 4294967232。如果把这个值右移 5 位,结果就变成了00000111111111111111111111111110,即十进制的 134217726。

原文地址:https://www.cnblogs.com/AAABingBing/p/12684395.html

时间: 2024-09-28 16:03:33

【JavaScript】JavaScript位操作符的相关文章

为什么不要在 JavaScript 中使用位操作符?

如果你的第一门编程语言不是 JavaScript,而是 C++ 或 Java,那么一开始你大概会看不惯 JavaScript 的数字类型.在 JavaScript 中的数字类型是不区分什么 Int,Float,Double,Decimal 的.咳咳,我说的当然是在 ES6 之前的 JS,在 ES6 的新标准中提出了像 Int8Array 这样新的数据类型.不过这不是本文叙述的重点,暂且就不谈啦.本文将更着重地谈 JS 的数字类型以及作用于它的位操作符,而关于包装对象 Number 的更多了解可以

从头开始学JavaScript 笔记(四)——操作符

一.一元操作符 1.自增自减操作符:分为前置型和后置型: 前置型:++a;--a; 后置型:a++;a--; 例: 1 <script type="text/javascript"> 2 var a, b,i= 1,j=1; 3 a=i++; 4 b=++j; 5 alert("a="+a+",i="+i+",b="+b+",j="+j);//a=1,i=2,b=2,j=2 6 </scr

javascript运算符——位运算符

× 目录 [1]二进制 [2]非 [3]与[4]或[5]异或[6]左移[7]右移[8]>>>[9]应用 前面的话 位运算符是非常底层的运算,由于其很不直观,所以并不常用.但是,其速度极快,且合理使用能达到很好的效果.本文将介绍javascript中常常被忽视的运算符——位运算符 二进制表示 ECMAScript中的所有数值都以IEEE-754 64位格式存储,但位操作符并不直接操作64位的值,而是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数 这种位数转换使得在对特

javascript中的操作符详解1

好久没有写点什么了,根据博主的技术,仍然写一点javascript新手入门文章,接下来我们一起来探讨javascript的操作符. 一.前言 javascript中有许多操作符,但是许多初学者并不理解或曲解他们的用途,本章将会带领初学者们一起来学习一下javascript的几个常用操作符:typeof.in.delete.new. 二.学习目标 1. 深入了解javascript操作符:typeof.in.delete.new的功能及用法. 2. 剖析根本,掌握这些常用的操作符的运用场景,活学活

javascript 中 in操作符

in in 操作检查对象中是否有名为 property 的属性.也可以检查对象的原型,以便知道该属性是否为原型链的一部分. 对于一般的对象属性需要用字符串指定属性的名称 ? 1 2 3 var mycar = {make: "Honda", model: "Accord", year: 1998}; "make" in mycar  // returns true "model" in mycar // returns tru

JavaScript 的in 操作符 (“如何判断某值是否数组中的元素”?)

在编写JavaScript时,遇到一个常见的问题"如何判断某值是否数组中的元素"?这让我想起了PHP中的in_array()函数和Python中in 操作符.但JavaScript似乎没有内置类似的函数,而其in 操作符的作用也有点不同.通过查询相关的资料,我发现JavaScript的in 操作符还是挺有用的. 一.问题让我想到in 操作符,正是因为这样一个问题:"如何判断某值是否数组中的元素"?在PHP中,您可能会这样来处理: $os = array("

【转载】在JavaScript中使用操作符void返回undefined

在JavaScript中使用操作符void返回undefined技术 maybe yes 发表于2014-12-30 18:45 原文链接 : http://blog.lmlphp.com/archives/53  来自 : LMLPHP后院 在 JavaScript 函数中返回 undefined 的同时执行一个表达式,可以使用 void 关键字.大家比较熟悉的 void 的用法一般都是在链接的 href 属性中,可以屏蔽<a>标签的默认行为.请看下面的代码片段: <script>

JavaScript 32位整型无符号操作

在 JavaScript 中,所有整数字变量默认都是有符号整数,这意味着什么呢? 有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数. 数值范围从 -2^31 - 2^31-1 即 -2147483648 到 2147483647. JavaScript 进行位操作时,是采用32位 有符号 整型,这意味着其转换的结果也是32位有符号整型. 有些时候,我们进行移位会出现意想不到的结果,以下是C语言 与 JS 的对比. C语言 1 unsigned in

JS位操作符

位运算 NOT位运算 NOT 由否定号(~)表示,它是 ECMAScript 中为数不多的与二进制算术有关的运算符之一. 位运算 NOT 是三步的处理过程: 1.把运算数转换成 32 位数字2.把二进制数转换成它的二进制反码3.把二进制数转换成浮点数例如: var iNum1 = 25;  //25 等于      00000000000000000000000000011001var iNum2 = ~iNum1; //转换为 11111111111111111111111111100110a