javascript位运算将操作数转为32位有符号整数,先tonumber再toint32:nan/infinity变0,小数舍弃,大数取模2³²,负数按补码映射;>>>例外,转为32位无符号整数。

JavaScript 中的 Number 类型在位运算中会自动转为 32 位有符号整数,这个过程会截断小数、处理溢出,并对超出范围的值取模,这是位运算结果“看似奇怪”但完全可预测的核心原因。
位运算前的强制类型转换
所有位运算符(&、|、^、、>>、>>>)都会先把操作数转为 32 位有符号整数(即 ToInt32 抽象操作)。这个转换分三步:
- 先调用
ToNumber,把非数字值转成数字(如"123"→123,null→0,undefined→NaN) - 若结果是
NaN、+Infinity、-Infinity,统一变成0 - 否则取数值的整数部分,再对
2³²取模,最后按补码规则解释为带符号的 32 位整数
小数和大数的截断表现
小数会被直接舍弃(不是四舍五入),只保留整数部分;超过 32 位能表示范围(±2³¹ − 1)的数会“绕回”:
-
5.7 | 0→5(小数部分丢弃) -
-3.9 | 0→-3(同样只取整,不向上取整) -
Math.pow(2, 32) | 0→0(因为2³² ≡ 0 (mod 2³²)) -
0x100000000 | 0→0,0x100000001 | 0→1
负数的补码处理细节
负数不会简单地截断符号位,而是按二进制补码规则映射到 32 位空间。例如:
-
-1 | 0→-1,对应 32 位补码全为 1(0xFFFFFFFF) -
-2147483649 | 0→2147483647(即2³¹ − 1),因为该值比最小的 32 位有符号整数−2³¹还小 1,绕回到最大正数 -
~0是-1,因为按位取反后补码解释就是 −1
无符号右移(>>>)的特殊性
>>> 是唯一不把结果当作有符号数的操作:它始终将操作数转为 32 位无符号整数(ToUint32),高位补 0。因此:
-
-1 >>> 0→4294967295(即2³² − 1) -
-2147483648 >>> 0→2147483648(最小的负数变成最大的无符号正数) - 常用于安全获取 32 位无符号整数值,比如
arr.length >>> 0防止length不是有效整数时出错
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











