No more than code.
常用的7个位运算符,以及在JS中的妙用
- 位运算直接对二进制位进行计算,位运算直接处理每一个比特位,是非常底层的运算,好处是速度极快,缺点是很不直观,许多场合不能够使用。
- 位运算只对整数起作用,如果一个运算数不是整数,会自动转为整数后再运行。
- 在JavaScript内部,数值都是以64位浮点数的形式储存,但是做位运算的时候,是以32位带符号的整数进行运算的,并且返回值也是一个32位带符号的整数。
JS中常用的7个位运算符
按位与(AND) &
&以特定的方式组合操作二进制数中对应的位,如果对应的位都为1,那么结果就是1, 如果任意一个位是0 则结果就是0。
1的二进制表示为: 00000000 00000000 00000000 00000001
3的二进制表示为: 00000000 00000000 00000000 00000011
console.log(1 & 3) // 1
按位或(OR) |
| 运算符跟 & 的区别在于如果对应的位中任一个操作数为1 那么结果就是1。
1的二进制表示为: 00000000 00000000 00000000 00000001
3的二进制表示为: 00000000 00000000 00000000 00000011
console.log(1 | 3) // 3
按位异或(XOR) ^
^ 如果对应两个操作位有且仅有一个1时结果为1,其他都是0。
1的二进制表示为: 00000000 00000000 00000000 00000001
3的二进制表示为: 00000000 00000000 00000000 00000011
2的二进制表示为: 00000000 00000000 00000000 00000010
console.log(1 ^ 3) // 2
按位非(NOT) ~
~ 运算符是对位求反,1变0, 0变1,也就是求二进制的反码。
1的二进制表示为: 00000000 00000000 00000000 00000001 3的二进制表示为: 00000000 00000000 00000000 00000011 1反码二进制表示: 11111111 11111111 11111111 11111110
简单记忆:一个数与自身的取反值相加等于-1
左移(Left shift)«
« 运算符使指定值的二进制数所有位都左移指定次数,其移动规则:丢弃高位,低位补0即按二进制形式把所有的数字向左移动对应的位数,高位移出(舍弃),低位的空位补零。
1的二进制表示为: 00000000 00000000 00000000 00000001 2的二进制表示为: 00000000 00000000 00000000 00000010
console.log(1 << 1) // 2
有符号右移»
>> 该操作符会将指定操作数的二进制位向右移动指定的位数。向右被移出的位被丢弃,拷贝最左侧的位以填充左侧。由于新的最左侧的位总是和以前相同,符号位没有被改变。所以被称作“符号传播”。
1的二进制表示为: 00000000 00000000 00000000 00000001 0的二进制表示为: 00000000 00000000 00000000 00000000
console.log(1 >> 1) // 0
无符号右移>>>
>>>该操作符会将第一个操作数向右移动指定的位数。向右被移出的位被丢弃,左侧用0填充。因为符号位变成了 0,所以结果总是非负的。(译注:即便右移 0 个比特,结果也是非负的。)对于非负数,有符号右移和无符号右移总是返回相同的结果。例如, 9 »> 2 得到 2 和 9 » 2 相同。
位运算符在js中妙用
使用~, », «, >>>, |来取整
console.log(~~ 6.83)
console.log(6.83 >> 0)
console.log(6.83 << 0)
console.log(6.83 | 0)
=> > 浮点数不支持位运算,所以会先把1.1转成整数1再进行位运算
console.log(6.83 >>> 0)
=> >>>不可对负数取整
使用&, », |来完成rgb值和16进制颜色值之间的转换
/*** 16进制颜色值转RGB*
@param {String} hex 16进制颜色字符串*
@return {String} RGB颜色字符串*/
function hexToRGB(hex) {
var hexx = hex.replace('#', '0x');
var r = hexx >> 16;
var g = hexx >> 8 & 0xff;
var b = hexx & 0xff;
return `rgb(${r}, ${g}, ${b})`
}
/*** RGB颜色转16进制颜色*
@param {String} rgb RGB进制颜色字符串*
@return {String} 16进制颜色字符串*/
function RGBToHex(rgb) {
var rgbArr = rgb.split(/[^\d]+/);
var color = rgbArr[1]<<16 | rgbArr[2]<<8 | rgbArr[3];
return '#'+ color.toString(16)
}
// -------------------------------------------------
hexToRGB('#ffffff') // 'rgb(255,255,255)'
RGBToHex('rgb(255,255,255)') // '#ffffff'参考
调换两个数字的值
-
常规方法
var num1 = 1, num2 = 2, temp; temp = num1; num1 = num2; // 2 num2 = temp; // 1
-
位运算
// 方法一 var num1 = 1, num2 = 2; num1 = [num2, num2 = num1][0]; console.log(num1); // 2 console.log(num2); // 1 // 方法二 var num1 = 1, num2 = 2; num1 ^= num2; // num1 = num1 ^ num2 = 1 ^ 2 = 3 num2 ^= num1; // num2 = num2 ^ (num1 ^ num2) = 2 ^ (1 ^ 2) = 1 num1 ^= num2; // num1 = num1 ^ num2 = 3 ^ 1 = 2 console.log(num1); // 2 console.log(num2); // 1
判断奇数偶数
-
余数判断:
function assert(n) { if (n % 2 === 1) { console.log("n是奇数"); } else { console.log("n是偶数"); } } assert(3); // "n是奇数"
-
按位&判断:
奇数的二进制码的最后一位数肯定是1,而1只有最后一位为1,按位&操作之后,结果肯定只有最后一位数为1。
偶数的二进制表示的最后一位数是0,和1进行按位&操作,结果所有位数都为0。function assert(n) { if (n & 1) { console.log("n是奇数"); } else { console.log("n是偶数"); } } assert(3); // "n是奇数"
2的n次方
function power(n) {
return 1 << n;
}
power(5); // 32
二分之一
64 >> 1; // 32