原文地址:https://wangdoc.com/javascript/
概述
二进制位运算符用于直接对二进制位进行计算,一共7个。
- 二进制或运算符(or):符号为|,表示若两个二进制位都为0,则结果为0,否则为1。
- 二进制与运算符(and):符号为&,表示若两个二进制位都为1,则结果为1,否则为0。
- 二进制否运算符(not):符号为~,表示对一个二进制位取反。
- 异或运算符(xor):符号为^,表示若两个二进制位不相同,则结果为1,否则为0。
- 左移运算符(left shift):符号为<<。
- 右移运算符(left shift):符号为>>。
- 带符号位的右移运算符(zero filled right shift):符号为>>>。
这些为运算符直接处理每一个比特位,所以是非常底层的运算,好处是速度急快,缺点是很不直观。
有一点需要注意,**位运算符只对整数起作用,如果一个运算子不是整数,会自动转为整数后再执行。另外,虽然在JavaScript内部,数值都是以64位浮点数的形式储存,但是做位运算的时候,是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数。
i = i | 0;
上面这行代码的意思就是将i(不管是整数或小数)转为32位整数。利用这一特性,可以写一个函数,将任意数值转为32位整数。
function toInt32(x) {
return x | 0;
}
toInt32(1.001) // 1
toInt32(1.999) // 1
toInt32(1) // 1
toInt32(-1) // -1
toInt32(Math.pow(2, 32) + 1) // 1
toInt32(Math.pow(2, 32) - 1) // -1
上面代码中,toInt32可以将小数转为整数。对于一般的整数,返回值不会有任何改变。对于大于或等于2的32次方的整数,大于32位的数位都会被舍去。
二进制或运算符
如上。
二进制与运算符
二进制与运算符(&)的规则是逐位比较两个运算子,两个二进制位之中只要有一个位为0,就返回0,否则返回1。
二进制否运算符
二进制否运算符(~)将每个二进制位都变为相反值。
~ 3 // -4
上面表达式对3进行二进制否运算,得到-4。之所以会得到这样的结果,是因为运算时,JavaScript内部将所有的运算子都转为32位的二进制整数再进行运算。
3的32位整数形式是00000000000000000000000000000011,二进制否运算之后得到的是11111111111111111111111111111100。由于第一位是1,所以这个数是一个负数。JavaScript内部采用补码形式表示负数,即需要将这个数减去1再取反,然后加上负号,才能得到这个负数对应的10进制值。这个数减1之后得到11111111111111111111111111111011,再取反得到00000000000000000000000000000100,再加上负号就是-4。考虑到这样的过程比较麻烦,可以简单记忆成,一个数与自身取反值相加等于-1。
对于一个整数,连续两次二进制否运算,得到它自身。
二进制否运算遇到小数时,也会将小数部分舍去,只保留整数部分。所以,对一个小数连续两次进行二进制否运算,能达到取整的效果。使用二进制否运算取整,是所有取整方法中最快的一种。
~~2.9 // 2
对字符串进行二进制否运算,JavaScript引擎会先调用Number函数,将字符串转为数值。
对于其他类型的值,二进制否运算也是先用Number转为数值,然后再进行处理。
异或运算符
异或运算有一个特殊运用,连续对两个数进行三次异或运算,可以互换它们的值。这是互换两个变量的值的最快的方法。
var a = 10;
var b = 99;
a ^= b, b ^= a, a ^= b;
a // 99
b // 10
异或运算也可以用来取整。
左移运算符
左移运算符(<<)表示将一个数的二进制值向左移动指定的位数,尾部补0,即乘以2指定的次方。如果左移0位,就相当于将该数值转为32位整数,等同于取整,对于正数和负数都有效。
例如:
var color = {r: 186, g: 218, b: 85};
// RGB to HEX
// (1 << 24)的作用为保证结果是6位整数
var rgb2Hex = function(r, g, b) {
return "#" + ((1 << 24) + (r << 16) + (g << 8) + b)
.toString(16) // 先转成十六进制,然后返回字符串
.substr(1); // 去除字符串的最高位,返回后面六个字符
}
右移运算符
右移运算符(>>)表示将一个二进制向右移动指定的位数,头部补0,即除2的指定次方,最高位符号位不参与移动。
带符号位的右移运算符
带符号位的右移运算符(>>>)表示将一个数的二进制形式向右移动,包括符号位也参与移动,头部补0。所以该运算总是得到正值。