位运算
按位与 (AND) 运算符
&
- 操作:两个位都为 1 时,结果为 1,否则为 0。
- 示例:
let a = 5; // 0101 let b = 3; // 0011 console.log(a & b); // 0001 => 1
按位或 (OR) 运算符
|
- 操作:两个位中有一个为 1,结果为 1,否则为 0。
- 示例:
let a = 5; // 0101 let b = 3; // 0011 console.log(a | b); // 0111 => 7
按位异或 (XOR) 运算符
^
- 操作:两个位中有且只有一个为 1,结果为 1,否则为 0。
- 示例:
let a = 5; // 0101 let b = 3; // 0011 console.log(a ^ b); // 0110 => 6
按位非 (NOT) 运算符
~
- 操作:按位取反,将 0 变为 1,1 变为 0。
- 示例:
let a = 5; // 0101 console.log(~a); // 1010 => -6 (注意是负数,因为二进制补码表示法)
左移 (Left Shift) 运算符
<<
- 操作:将位左移指定的次数,高位丢弃,低位补 0。
- 示例:
let a = 5; // 0101 console.log(a << 1); // 1010 => 10
右移 (Right Shift) 运算符
>>
- 操作:将位右移指定的次数,符号位不变,高位补符号位(保持符号)。
- 示例:
let a = 5; // 0101 console.log(a >> 1); // 0010 => 2 let b = -5; // 11111011 (补码表示) console.log(b >> 1); // 11111101 => -3
无符号右移 (Unsigned Right Shift) 运算符
>>>
- 操作:将位右移指定的次数,高位补 0,不考虑符号位。
- 示例:
let a = 5; // 0101 console.log(a >>> 1); // 0010 => 2 let b = -5; // 11111011 (补码表示) console.log(b >>> 1); // 01111101 => 2147483645
使用情景实现
判断奇偶性
- 场景:快速判断一个数是奇数还是偶数。
- 实现:
function isOdd(num) { return (num & 1) === 1; } console.log(isOdd(5)); // true console.log(isOdd(4)); // false
交换两个变量的值(不使用临时变量)
- 场景:在算法中快速交换两个变量的值。
- 实现:
let a = 5, b = 3; a = a ^ b; b = a ^ b; a = a ^ b; console.log(a, b); // 3, 5
清除最低位的 1
- 场景:在位操作算法中,快速清除一个数的最低位的 1。
- 实现:
function clearLowestBit1(num) { return num & (num - 1); } console.log(clearLowestBit1(10)); // 8 (1010 -> 1000)
获取一个数的绝对值
- 场景:快速获取一个整数的绝对值。
- 实现:
function absoluteValue(num) { const mask = num >> 31; return (num + mask) ^ mask; } console.log(absoluteValue(-5)); // 5 console.log(absoluteValue(5)); // 5
计算两个数的平均值(防止溢出)
- 场景:在处理大整数时,防止溢出。
- 实现:
function average(x, y) { return (x & y) + ((x ^ y) >> 1); } console.log(average(10, 20)); // 15 console.log(average(11, 21)); // 16
位掩码
场景:使用位掩码来启用或禁用特定位。
实现:
const FLAG_A = 1 << 0; // 0001 const FLAG_B = 1 << 1; // 0010 const FLAG_C = 1 << 2; // 0100 let flags = 0; flags |= FLAG_A; // 打开 FLAG_A flags |= FLAG_C; // 打开 FLAG_C console.log(flags); // 0101 // 检查 FLAG_B 是否打开 if (flags & FLAG_B) { console.log('FLAG_B is set'); } else { console.log('FLAG_B is not set'); }