在ECMAScript中,有少数的几个操作符可以对二进制位进行直接操作,这几个操作符本身直接对二进制进行操作,所有它们的本身是非常效率的,学习这一段有助于以后的优化以及理解。 ECMAScript中采用IEEE-754 64位格式存储,但是在开发的过程中不是直接操作的64位,而是后台会先将64位的数据转换位32位,然后让开发者进行操作,最后再填充成64位存储。但是在转换的过程中也会有一个副效应,那就是在对NaN和Infinity的时候,这两个值会被当成0进行处理。对于非数值使用位操作符,会先使用Number()转型函数进行转换为一个数值。 要了解位操作符,首先得来属性一点底层的知识,在计算机中数值分有符号数(如:+40和-40)和无符号数(如:40),这两种数值在二进制里是用不同的表示。
无符号数
无符号数比较好理解,具体怎么转换的就不多过说。如无符号数40,二进制表示为:
有符号数
有符号数稍微要难一点,在有符号数里面第32位用于表示负数或者正数(0表示正数,1表示负数),第32位一般称为”符号位”。有符号数中正数的表示方法和无符号数都表示一样。如有符号数+40,二进制表示为:
如何表示一个有符号数的负数,这个负数的绝对值取反加1,这个过程加做补码,补码就是为了解决负数在二进制中的表示。如有符号数-40,二进制计算过程为:
+ ———————————————- -
按位非(NOT)
按位非由一个波浪线(~)表示,按位非的操作是将给定的数值按位取反,如:
var test = 40; 二进制为: 0000 0000 0000 0000 0000 0000 0010 1000 test = ~test; 二进制为: 1111 1111 1111 1111 1111 1111 1101 0111
按位与(AND)
按位与由一个和符号表示(&),按位与有两个操作数,分别对两个操作数进行按位对比,如果对应的位上都为1则当前位返回1,如果对应的位上有一个为0则返回当前位0,如:
var test1 = 40; 二进制为: 0000 0000 0000 0000 0000 0000 0010 1000 var test2 = 50; 二进制为: 0000 0000 0000 0000 0000 0000 0011 0010 var test3 = test1 & test2; 二进制为: 0000 0000 0000 0000 0000 0000 0010 0000
按位或(OR)
按位或由一个竖线符号(|)表示,按位或有两个操作数,分别对两个操作数进行按位对比,对应的位上只要有一个为1则返回当前位1,如果都为0则返回当前位为0。如:
var test1 = 40; 二进制为: 0000 0000 0000 0000 0000 0000 0010 1000 var test2 = 50; 二进制为: 0000 0000 0000 0000 0000 0000 0011 0010 var test3 = test1 | test2; 二进制为: 0000 0000 0000 0000 0000 0000 0011 1010
按位异或(XOR)
按位异或由一个插入符号(^)表示,按位异或有两个操作数,分别对两个操作数进行按位对比,对应的位上只要有一个1则返回当前位1,如果都是1或者都是0则返回当前位0
var test1 = 40; 二进制为: 0000 0000 0000 0000 0000 0000 0010 1000 var test2 = 50; 二进制为: 0000 0000 0000 0000 0000 0000 0011 0010 var test3 = test1 | test2; 二进制为: 0000 0000 0000 0000 0000 0000 0001 1010
左移(<<)
左移操作符由两个小于号表示(<<),左移操作符用于将当前数值从第0位开始按位向左移。如:
var test = 2; 二进制为:10 var newTest = 2 << 5; 二进制为: 1000000
有符号数右移(>>)
有符号数右移由两个大于符号(>>)组成,有符号数由于第32位是符号位,所以不会移动符号位,所以从第31位右移,但是右移过程中产生的空位用符号位的值来填充。如下例用8位来示范:
var test = -2; 二进制为: 1000 0010 var newTest = 2 >> 5; 二进制为: 11111100
无符号数右移(>>>)
无符号数右移由三个大于符号组成(>>>),无符号数第32位不属于符号位,所以右移的时候是从第32位开始移动。如下例用8位来示范:
var test = 2; 二进制为: 0000 0010 var newTest = 2 >>> 5; 二进制为: 0000 0000