JavaScript位运算符强制将操作数转为32位有符号整数执行补码运算,再转回64位浮点数;支持&、|、~、^、<<、>>、>>>七种操作,适用于取整、开关控制等场景,但仅对整数语义有效。

JavaScript 的 Number 类型本身不“存储”二进制位,它底层用 IEEE 754 双精度浮点格式(64 位)表示所有数值;但**位运算符(如 &、|、~、<<、>>、>>>)会强制将操作数转为 32 位有符号整数再处理**——这才是真正发生二进制位操作的环节。
位运算前:一律转成 32 位有符号整数
无论原始值是小数、负数、大数还是字符串,只要参与位运算,就会先走 ToInt32 抽象操作:
- 非数字(如
"abc"、null、undefined)→ 先转Number()→ 得NaN→ToInt32(NaN)返回0; - 小数(如
3.9、-2.1)→ 直接截断小数部分,只留整数部分(不是四舍五入),即ToInt32(3.9) === 3,ToInt32(-2.1) === -2; - 超出 32 位范围的数(如
Math.pow(2, 32)即4294967296)→ 对2³²取模,所以4294967296 & 1 === 0; - 无穷大(
Infinity)、负无穷(-Infinity)→ 统一转为0。
位运算中:按补码进行 32 位逐位计算
转换后的两个 32 位整数,以二进制补码形式对齐(共 32 位,最高位为符号位),再执行对应逻辑:
-
&、|、^:对应位做布尔与/或/异或,结果仍是 32 位整数; -
~x:等价于-(x + 1),因为补码下按位取反 = 取负减 1(如~5→-6); -
x << n:左移n位,右侧补 0,高位溢出直接丢弃; -
x >> n:算术右移,左侧补符号位(保持正负性),适合带符号整数; -
x >>> n:无符号右移,左侧一律补 0,结果恒为 ≥ 0 的 32 位无符号整数(如-1 >>> 0→4294967295,即0xFFFFFFFF)。
位运算后:结果转回标准 Number 类型
运算完成后的 32 位整数,通过 ToNumber 转为 JavaScript 的 Number 类型(IEEE 754 双精度):
立即学习“Java免费学习笔记(深入)”;
- 值本身不变(
5 & 3得1,仍是精确整数); - 但注意:
1 << 31得-2147483648(即0x80000000),不是正数2147483648,因为最高位被解释为符号位; - 该结果可参与后续浮点运算,只要仍在
±2⁵³安全整数范围内,就保持精度无损。
为什么不能直接对浮点数做位运算?
因为位运算是定义在整数域上的逻辑操作。JavaScript 故意不支持对小数位做“逐位”处理——它没有小数的二进制位概念(小数在 IEEE 754 中由指数+尾数共同编码)。所谓“对 3.7 做 &”,实际是先砍掉 .7,再对 3 运算。这不是 bug,而是规范明确的设计:位运算只面向整数语义。


















