& (位与运算符)
真真为真,其余为假;
function oddEven(num) {
let result;
if(num & 1) {
// 1 的二进制是 0000 0001, 所以 num & 1 不是 1 就是 0,
// 奇数的二进制末尾是 1,偶数的二进制末尾是 0
result = `${num} 为奇数`
} else {
result = `${num} 为偶数`
}
return result;
}
console.log(oddEven(8)); // 8 为偶数
console.log(oddEven(9)); // 9 为奇数
console.log(oddEven(18));// 18 为偶数
console.log(oddEven(19));// 19 为奇数
| (位或运算符)
假假为假,其余为真;
整数与0的位或运算,都是本身,浮点数不支持位运算,过程中会自动转化成整数,利用这一点,可以将浮点数与0进行位或运算即可达到取整目的。
console.log(15.22 | 0) // 15
~ (位非运算符)
真为假,假为真;
位非运算符有一个规律,值为 - (x + 1);
// ~9 9 二进制位非运算
console.log(~9) // -10
// 0000 0000 0000 0000 0000 0000 0000 1001 // 先转换成32位的二进制
// 1111 1111 1111 1111 1111 1111 1111 0110 // 全部取反
// 1000 0000 0000 0000 0000 0000 0000 1001 // 符号位不变,其余取反
// 1000 0000 0000 0000 0000 0000 0000 1010 // 再加 1; -10
// 可以和indexOf结合使用;
let arr = [1, 2, 3];
// !~arr.indexOf(4) => arr.indexOf(4) == -1;
if(!~arr.indexOf(4)){
// indexOf没找到返回 -1,-1取反为 0, !0 为true,打印 arr 中没有 4
console.log('arr 中没有 4')
}
if(!!~arr.indexOf(1)){
// indexOf找到了返回这个值的下标,返回 0,0取反为-1,!!-1 为true, 打印 arr 中有 1
console.log('arr 中有 1')
}
^ (异或运算符)
相同为假,不同为真;
// 9 和 10 二进制异或运算
console.log(9^10); // 3
// 1001
// 1010
// ----
// 0011 // 结果为 3
// 实现两个值互换
let a = 3, b = 5;
a ^= b; // a = 3; b = 5; a ^ b = 6;且把值赋给 a // 0011 ^ 0101 = 0110 = 6
console.log(1, `a=${a}`, `b=${b}`); // a = 6; b = 5;
b ^= a; // a = 6; b = 5; a ^ b = 3; 且把值赋给 b // 0110 ^ 0101 = 0011 = 3
console.log(2, `a=${a}`, `b=${b}`); // a = 6; b = 3;
a ^= b; // a = 6, b = 3; a ^ b = 5; 且把值赋给 a // 0110 ^ 0011 = 0101 = 5
console.log(3, `a=${a}`, `b=${b}`); // a = 5; b = 3;
<< (有符号左移)
首位符号不动,把32位二进制数字整体往左边移动指定的位数,左边超出部分舍去,右边补0
console.log(9<<5); // 288
// 0000 0000 0000 0000 0000 0000 0000 0000 1001
// 0000 0000 0000 0000 0000 0000 0001 0010 0000
// 2 的 8 次方 + 2的 5次方 = 256 + 32 = 288
// 可以通过计算公式: num * (2^n), 即 9*Math.pow(2,5)
>> (有符号右移)
首位符号不动,把32位二进制数字整体往右边移动指定位数,右边超出部分被舍去,左边补0。
console.log(288>>5); // 9
// 0000 0000 0000 0000 0000 0000 0001 0010 0000
// 0000 0000 0000 0000 0000 0000 0000 0000 1001
// 可以通过计算公式:num/(2^n),即 288/Math.pow(2,5)
>>> (无符号右移)
符号为也跟着一起移动,这样,无符号右移会把负数的二进制当成整数的二进制码
// 4294967296 >>> 5 = 0;
// 二进制最大存储的值是 2^32-1;
// 即 0111 1111 1111 1111 1111 1111 1111 1111,最高位为符号位,0表示正,1表示负
// 288>>>5 = 9;
// 正数的无符号右移和有符号右移值基本一样,除非数值太大二进制存储不下
面试题
let num = 10;
num ^= (1<<4) -1;
console.log(num); // 5
// 1<<4 = 10000 = Math.pow(2,4) = 16
// 16 - 1 = 15
// a ^= 15; 1010 ^ 1111 = 0101 = 5; 并把值赋给 a;