JavaScript中的位操作符

262 阅读2分钟

JavaScript的数字类型为双精度IEEE 754 64位浮点类型, 但是在位运算中位运算符用于32位的数字上, 任何的数字操作都将转为32位, 运算结果再转化为JavaScript数字类型

描述

所有的按位操作符的操作数都会被转成补码形式的有符号32位整数, 从概念上讲, 按位逻辑操作符按遵守下面规则:

  • 操作数被转换成32位整数, 用比特序列(01组成)表示, 超过32位的数字会被丢弃
  • 第一个操作数的每个比特位与第二个操作数的相应比特位匹配, 第一位对应第一位, 第二位对应第二位, 以此类推
  • 位运算符应用到每对比特位, 结果是新的比特值
& 按位与(AND)

对于每一个比特位, 只有两个操作数相应的比特位都是1时, 结果才为1, 否则为0, 真值表如下

aba & b
000
010
100
111

我们可以使用&操作符来判断数值的奇偶性

console.log(7 & 1);					// 1
console.log(8 & 1);					// 0
| 按位或(OR)

对于每一个比特位, 当两个操作数相应的比特位至少有一个1时, 结果为1, 否则为0, 真值表如下

aba & b
000
011
101
111

我们可以使用|操作符来强制转换值为int 3232位整数类型

console.log(11.11 | 0);			// 11
console.log("11.11" | 0);		// 11
console.log("-11.11" | 0);	// -11
console.log(1.23E2 | 0);		// 123
console.log([] | 0);				// 0
console.log({} | 0);				// 0
^ 按位异或(XOR)

对于每一个比特位, 当两个操作数相应的比特位有且只有一个1时, 结果为1, 否则为0, 真值表如下

aba & b
000
011
101
110

我们可以使用^操作符来交换数值

let a = 7;
let b = 1;
a ^= b;
b ^= a;
a ^= b;
console.log(a);							// 1
console.log(b);							// 7

// 也可以借助数组
b = [a, a = b][0];

// 当然解构赋值更简单
[a, b] = [b, a];

也可以用来判断值的符号是否相同

let a = 1;
let b = 1;
console.log((a ^ b) >= 0);		// true
console.log((a ^ -b) >= 0);		// false
~ 按位非(NOT)

对于每一个比特位, 反转操作数的比特位, 即0变成1, 1变成0, 真值表如下 | a | ~a | | 0 | 1 | | 1 | 0 |

我们可以使用~操作符来强制转换值为int 3232位整数类型

console.log(~~(11.11));				// 11
console.log(~~("11.11"));			// 11
console.log(~~("-11.11"));		// -11
console.log(~~(1.23E2));			// 123
console.log(~~([]));					// 0
console.log(~~({}));					// 0
<< 左移

将值的二进制形式向左移n (n < 32)比特位, 右边用0填充 我们可以使用<<操作符来进行整数的*2^n运算

console.log(11 << 2);					// 44
console.log(11.11 << 1);			// 22
console.log("11.11" << 1);		// 22

我们可以使用<<操作符来强制转换值为int 3232位整数类型

console.log(11.11 << 0);			// 11
console.log("11.11" << 0);		// 11
console.log("-11.11" << 0);		// -11
console.log(1.23E2 << 0);			// 123
console.log([] << 0);					// 0
console.log(({}) << 0);				// 0
>> 右移

将值的二进制表示向右移n(n < 32)位, 丢弃被移出的位 我们可以使用<<操作符来进行整数的/ 2^n运算

console.log(32 >> 2);					// 8
console.log(32.11 >> 1);			// 16
console.log("32.11" >> 1);		// 16

我们可以使用>>操作符来强制转换值为int 3232位整数类型

console.log(11.11 >> 0);			// 11
console.log("11.11" >> 0);		// 11
console.log("-11.11" >> 0);		// -11
console.log(1.23E2 >> 0);			// 123
console.log([] >> 0);					// 0
console.log(({}) >> 0);				// 0