位运算是直接对二进制位进行操作的一种运算。在 JavaScript 中,位运算符包括 &
(按位与)、|
(按位或)、^
(按位异或)、~
(按位非)、<<
(左移)和 >>
(右移)等。下面我将详细介绍这些位运算符,并给出相应的代码示例。
1. 按位与(&)
按位与运算符对两个数的每一位执行与操作。如果两个相应的二进制位都为 1,则结果为 1,否则为 0。
示例代码:
let a = 5; // 二进制: 101
let b = 3; // 二进制: 011
console.log(a & b); // 输出: 1 (二进制: 001)
2. 按位或(|)
按位或运算符对两个数的每一位执行或操作。如果两个相应的二进制位至少有一个为 1,则结果为 1,否则为 0。
示例代码:
let a = 5; // 二进制: 101
let b = 3; // 二进制: 011
console.log(a | b); // 输出: 7 (二进制: 111)
3. 按位异或(^)
按位异或运算符对两个数的每一位执行异或操作。如果两个相应的二进制位值不同,则结果为 1,否则为 0。
示例代码:
let a = 5; // 二进制: 101
let b = 3; // 二进制: 011
console.log(a ^ b); // 输出: 6 (二进制: 110)
4. 按位非(~)
按位非运算符对一个数的每一位执行非操作。如果该位为 1,则结果为 0,如果该位为 0,则结果为 1。注意,在 JavaScript 中,按位非运算的结果是带符号的 32 位整数。
示例代码:
let a = 5; // 二进制: 101
console.log(~a); // 输出: -6 (二进制: -(000...0110),注意这里省略了前面的多个0)
5. 左移(<<)
左移运算符将一个数的所有位向左移动指定的位数。左移 n 位相当于将该数乘以 2^n。
示例代码:
let a = 5; // 二进制: 101
console.log(a << 1); // 输出: 10 (二进制: 1010,相当于 5 * 2^1)
6. 右移(>>)
右移运算符将一个数的所有位向右移动指定的位数。右移 n 位相当于将该数除以 2^n 并向下取整。
示例代码:
let a = 10; // 二进制: 1010
console.log(a >> 1); // 输出: 5 (二进制: 101,相当于 10 / 2^1 向下取整)
请注意,JavaScript 中的位运算符处理的是 32 位有符号整数,因此对于非常大的数或非常小的数,可能会出现意外的结果。在使用位运算时,请务必注意数值范围。
与0、1的运算
当一个数与 1 进行按位或运算时,实际上这个操作并不会改变原数的值(针对整数而言)。这是因为按位或运算会比较每一个二进制位,只有当两个比较的位不同时,结果才为 1;否则结果为 0。而与 1 进行按位或运算时,只有原数的该位为 0 时,结果才会变为 1,否则保持不变。
示例代码:
let a = 5; // 二进制: 0101 (假设我们只考虑低4位)
console.log(a | 1); // 输出: 5 (二进制: 0101,因为 5 的最低位已经是 1,所以与 1 进行按位或运算后值不变)
let b = 4; // 二进制: 0100
console.log(b | 1); // 输出: 5 (二进制: 0101,因为 4 的最低位是 0,与 1 进行按位或运算后变为 1)
但是,如果你考虑的是浮点数,情况就会有所不同。JavaScript 会将浮点数转换为 32 位有符号整数(通过截断小数部分)后再进行按位运算。因此,与 1 进行按位或运算实际上只会影响整数部分的最右边一位。
示例代码:
let c = 5.7; // 浮点数
console.log(c | 1); // 输出: 5 (因为 5.7 被转换为整数 5 后进行按位或运算)
let d = 4.2; // 浮点数
console下console.log(d | 1); // 输出: 5 (因为 4.2 被转换为整数 4 后进行按位或运算,结果变为 5)
总的来说,当一个整数与 1 进行按位或运算
时,只有在该整数的最低位为 0 时,结果才会改变;对于浮点数,与 1 进行按位或运算实际上只影响其整数部分的最右边一位。
当一个数与 0 进行按位或运算
时,JavaScript 会自动将该数转换为一个 32 位的整数,并舍弃小数部分。这种方法在某些情况下可以作为一种快速向下取整的技巧。