JavaScript的位操作符有:按位非,按位与,按位或,按位异或,左移,有符号的右移,无符号的右移。
基础:
- ECMAScript 整数有两种类型:有符号整数(允许用正数和负数)和无符号整数(只允许用正数)。在 ECMAScript 中,所有整数字面量默认都是有符号整数,有符号整数使用 31 位表示整数的数值,用第 32 位表示整数的符号,0 表示正数,1 表示负数。
- ECMAScript中正数以纯二进制格式存储,负数使用是二进制补码的格式存储。
- 补码:正数的补码就是其本身;负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1。
一、按位非
表示:~
结果:操作数的所有位取反。也等于操作数的负数-1。
var num1 = 20;
var num2 = ~num1;
console.log(num2);//-21
过程:
- num1二进制表示为 "00000000000000000000000000010100"
- num1每位取反,即"11111111111111111111111111101011"
- num1取反的最高位为1,表示负数,因为ECMAScript中负数使用是二进制补码的格式存储,所以求"11111111111111111111111111101011"的补码,即"10000000000000000000000000010101"。
- 将"10000000000000000000000000010101"用十进制表示,即 -21
二、按位与
表示:&
结果:操作数每位对齐,全1为1,否则为0
.
var num1 = 14;//01110
var num2 = 20;//10100
var num3 = num1 & num2;
console.log(num3);//4
var n1 = 14;
var n2 = -20;
var n3 = n1 & n2;
console.log(n3);//12
过程:
- num1二进制表示为"00000000000000000000000000001110",
- num2二进制表示为"00000000000000000000000000010100"
- 每位对齐相与: "00000000000000000000000000000100",转为十进制为 4。
- 负数是补码格式存储,所以 -20 的二进制表示为:"11111111111111111111111111101100",与num1每位对齐相与,结果为"00000000000000000000000000001100",即12
三、按位或
表示:|
结果:全0则0,否则为1。
var num1 = -20;
var num2 = 14;
var num3 = num1 | num2;
console.log(num3);//-18
过程:
- 负数是补码格式存储,所以-20的存储二进制表示为"11111111111111111111111111101100"
- 14的二进制表示为"00000000000000000000000000001110"
- 按位或操作,对应位有1则1。为:11111111111111111111111111101110,最高位为1,表示负数,负数按补码格式存储,所以转为补码为:10000000000000000000000000010010,用10进制表示为 -18
四、按位异或
表示:^
结果:操作数的二进制对应位只有一个“1”时结果为“1”,其余情况为“0”
var num1 = -20;
var num2 = 14;
var num3 = num1 ^ num2;
console.log(num3); //-30
过程:
- -20:"11111111111111111111111111101100"
- 14:"00000000000000000000000000001110"
- 对应位只一个“1”则“1”,结果:"11111111111111111111111111100010"
- 结果最高位为1,表示负数,负数用补码存储,所以转为补码为:"10000000000000000000000000011110",用10进制表示:-30
五、左移
表示:<<
结果:数值所有位向左移动指定位数,用0补全移动后空位。
var num1 = 3;
var num2 = num1<<2;
console.log(num2); //12
过程:
- 3的存储二进制码:00000000000000000000000000000011
- 3的存储二进制码向左移动2位,即:000000000000000000000000000011_ _
- 移动后右侧有了2个空位,用0补全,即:00000000000000000000000000001100,
- 最高位为0,正数,用十进制表示:12
六、有符号的右移
表示:>>
结果:数值所有位向右移动指定位,保留符号位,即符号位始终在第一位不移动;符号位的值补全移动后的空位。
var num1 = -20;
var num2 = num1>>2;
console.log(num2); //-5
过程:
- -20的存储二进制码:"11111111111111111111111111101100"
- 向右移动2位:"1_ _11111111111111111111111111011"
- 用符号位的值补全空位,即:"11111111111111111111111111111011"
- 最高位为1 ,即负数,所以转为补码形式"10000000000000000000000000000101",十进制表示:-5
七、无符号的右移
表示:>>>
结果:操作数的32位均向右移,用0补全移动后空位。
var num1 = -20;
var num2 = num1>>>30;
console.log(num2); //3
过程:
- -20的存储二进制码:"11111111111111111111111111101100"
- 32位全部向右移30位:"_ _ _ _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ __ _ _ _ _ _ _ _ _ _11"
- 空位用 0 补全,即:"00000000000000000000000000000011",
- 最高位为0,正数,用十进制表示:3