JavaScript中按位取反(~)对32位有符号补码整数逐位取反,结果仍为补码,需按补码规则解释为十进制数,故~5等于-6,通式为~n = -(n + 1)。

按位取反(~)在 JavaScript 中不是简单地把 0 变 1、1 变 0 后直接当结果用,它背后依赖的是整数的补码表示法。理解这一点,关键在于搞清三件事:JavaScript 怎么存整数、为什么用补码、以及取反后怎么还原成我们能看懂的十进制数。
JavaScript 整数默认是 32 位有符号补码
JS 所有按位运算都会先把操作数转为 32 位有符号整数(范围是 −2147483648 到 2147483647),然后以补码形式参与运算。这意味着:
- 正数的补码 = 它的二进制原码(比如 5 → 00000000 00000000 00000000 00000101)
- 负数的补码 = 先写绝对值的原码,再对除符号位外的所有位取反,最后 +1(比如 −5 的补码是 11111111 11111111 11111111 11111011)
- 计算机内部只认补码,加减法、取反、移位等操作都在补码上进行
按位取反 ~ 的真实过程是“对补码整体取反”
以 ~5 为例,不是对数字 5 的原码取反,而是:
- 5 的 32 位补码是:00000000 00000000 00000000 00000101
- 对这个补码逐位取反(包括最高位符号位)→ 11111111 11111111 11111111 11111010
- 这个结果本身仍是补码形式,需把它“解释”为十进制数:它最高位是 1,说明是负数;要得到对应数值,就对它再求一次补码(取反 +1),得到原码的绝对值部分,再加负号
- 对 11111111 11111111 11111111 11111010 取反得 00000000 00000000 00000000 00000101,再 +1 得 00000000 00000000 00000000 00000110 = 6 → 所以结果是 −6
所以 ~5 === −6,同理 ~9 === −10,规律就是:~n 等于 −(n + 1)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
补码让取反和加减逻辑自洽
补码设计的核心目的,是让减法变成加法,硬件只需一套加法电路。而按位取反配合补码,恰好满足这个规则:
- ~n + 1 === −n(这是补码定义决定的:负数补码 = 正数补码取反 +1)
- 因此 ~n === −n − 1,也就是前面说的恒等式
- 这也解释了为什么 ~~n 能“截断小数”:第一次 ~ 把数变负并减 1,第二次 ~ 再变回正并加 1,最终效果近似于 Math.floor(n)(对非负数而言)
实际写代码时不用手算补码,但得知道它在后台运行
你不需要每次写 ~5 都手动列 32 位二进制,但必须明白:
- JS 位运算永远基于 32 位补码,不是直观二进制
- 结果为负数时,是补码被自动解释出来的,不是你“写了个负号”
- 遇到浮点数如 ~3.7,JS 先取整(按向零截断)得 3,再走上面流程 → 结果仍是 −4

















