未运算符用于直接对二进制进行计算,一共有七个:
- 或运算符(or): 符号为
|
- 与运算符(and):符号为
&
- 否运算符(not):符号为
~
- 左移运算符(left shift):符号为
<<
- 右移运算符(right shift):符号为
>>
- 带符号位的右移运算符(zero filled right shift):符号为
>>>
位运算符直接处理每一个比特位(bit),是非常底层的运算,速度极快,缺点是不直观,许多场合不能使用它们。位运算符只对整数起作用。如果运算子不是整数,会自动转换为整数后再执行。JavaScript进制表示法
先复习下JavaScript中进制的表示法,进制有:二进制、八进制、十进制、十六进制。 - 二进制 表示二进制需要前缀
0b
,例如:0b100
,等于4 - 八进制 表示八进制需要前缀
0
,例如:022
,表示18,八进制不可有8和9数字,否则会当十进制来计算。 - 十进制 普通数字表示十进制
- 十六进制 表示十六进制需要前缀
0x
,例如:0x22
,表示34.
进制间的转换,十进制转换为其他进制:(number).toString(radix)
,括住数字才可以调用toString函数。其他进制转换为十进制:parseInt(string, radix)
,radix介于2~36之间。
虽然在JavaScript内部,数值都是以64位浮点数的形式存储,但是在做位运算的时候,是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数。利用这一特性,可以将任何数值转换为32位整数:
1 | function toInt32(x) { |
或运算符
或运算符|
逐位比较两个运算子,两个二进制位中只要有一个为1,就返回1,否则返回0。
比如:6 | 4
,6的二进制为110
,4的二进制为10
,所以他们的与运算的结果为110
,还是6.
位运算只对整数有效,遇到小数时,会将小数部分舍去,只保留整数部分。所以上面toInt32()
这个方法也实现了向下取整。**注意:取整方法不适用于超过32位整数最大值2147483647
的数。
与运算符
与运算符&
逐位比较两个运算子的二进制位之中只要有一个位为0,就返回0,否则返回1.
比如:6 & 4
,6的二进制为110
,4的二进制为10
,所以他们的与运算的结果为010
,为4.
否运算
否运算~
将没给二进制位都变为相反的值(0变1,1变0),它的返回结果比较复杂。
位运算时,JavaScript内部将所有的运算子都转为32位的二进制整数再进行运算。而32位整数的第一位是符号位。JavaScript内部采用补码方式表示负数,即需要将这个数减去1,再取一次反,然后加上符号,才能得到这个符号对应的10进制的值。
例如:3的32位整数形式是00000000000000000000000000000011
,否运算后得到11111111111111111111111111111100
,减去1得到11111111111111111111111111111011
,再取一次反得到00000000000000000000000000000100
,再加上负号得到-4
,即~3 // = -4
。
简单记忆:一个数与自身的取反值相加,等于-1。一个整数连续两次否运算,得到它自身。 ~~3 // 3
。
异或运算
异或运算^
在两个二进制位不同时返回1,相同时返回0。例如0 & 3
,3的二进制11
和0的二进制00
,运算后得到11
,即3.
异或运算连续对两个数进行三次异或运算,可以互换他们的值:
1 | var a = 10; |
左移运算符
左移运算符<<
表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2的指定次方(最高位即符号位不参与移动)。例如:4 << 1
,4的二进制为100,左移一位为1000,即8,相当于乘以2的1次方。
实例应用:rgb转hex
RGB是三通道颜色,相当于红绿蓝三个颜色通过不同的亮度,来组合为需要的颜色,0为最暗,255为最亮。
HEX是十六进制颜色,通过16进制0~F这16个字符来表达颜色,同样,000000位黑色,FFFFFF为白色。
RGB的三个通道的最大值为256,而256是16的平方,HEX为六位16进制的数字,每两位对应一个通道。即:
- RGB (x, y, z)
- HEX # aa bb cc
换句话说,RGB分别表示十进制的HEX,HEX表示16进制的RGB的一组数据。
将RGB转换为HEX,分别将RGB三个通道除以16,然后转化为十六进制,再拼在一块,就可以得到HEX。反之可以将HEX转换为RGB。使用左移运算符尝试下转换:
1 | function rgb2hex (r, g, b) { |
最前面加上(1<<24)
的作用是为了保证结果是6位数。
然后看看逆转,从hex到rgb:
1 | function hex2rgb(hex) { |
右移运算符
右移运算符(>>)表示将一个数的二进制向右移动指定的位数,头部补0,即除以2的指定次方(最高位即符号位不参与移动)。例如:4 >> 1
,4的二进制为10,右移一位为01
,即2.
右移运算可以模拟2的整除运算。
1 | 5 >> 1 // 2 |
带符号位的右移运算符
带符号的右移运算符(>>>)表示将一个数的二进制形式向右移动,包括符号位也参与移动,头部补0,所以该值总是得到正值。区别主要在负数(用在负数上也没啥意义,就不做例子了)。这个运算符的作用实际上是将一个值转为32位无符号整数。查看一个负整数在计算机内部的存储形式,最快的方法就是使用这个运算符。
参考文档:http://javascript.ruanyifeng.com/grammar/operator.html#toc27