无符号右移>>>对负数的处理是忽略符号、只看补码、高位硬填0,将操作数的32位(或64位)补码视为纯二进制串,右移后左侧补0,故结果恒为非负数,如-1>>>1得2147483647。

无符号右移 >>> 对负数的处理,核心在于“忽略符号、只看补码、高位硬填0”。它不关心这个数原本是正是负,而是把内存里存着的32位(或64位)补码,当成一串纯二进制数字来操作。
负数在内存中本来就是补码形式
Java 中所有整数都以补码存储。比如 -1 的 int 表示是 32 个 1:
11111111 11111111 11111111 11111111
这不是原码,也不是反码,就是它在内存里的真实样子。>>> 操作直接拿这串二进制开干,不转换、不解释、不判断符号。
>>> 的动作只有三步
- 取操作数的完整补码(32位 int 或 64位 long)
- 整体向右平移指定的位数
- 左边空出来的位置,一律补 0(不是复制符号位,也不是看正负)
结果为什么总是非负数
因为高位补的是 0,移完之后最高位(第31位)变成 0,而 Java 把这个结果仍按 int 类型解释——最高位为 0 就是有符号正数或零。例如:
-1 >>> 1 → 01111111 11111111 11111111 11111111 = 2147483647
-8 >>> 2 → 00111111 11111111 11111111 11111110 = 1073741822
容易踩坑的几个细节
- byte/short 运算前会自动提升为 int,所以 (byte)-1 >>> 1 不等于 -1 >>> 1,前者先扩成 int 再移,行为可能出人意料
- 移位量 ≥ 32(int)时,实际按 count & 0x1F 取模,比如 -1 >>> 33 等价于 -1 >>> 1
- long 类型必须显式写成 -1L >>> 1,否则还是按 int 算,可能截断或误判
- 它不是“求绝对值”也不是“转正数”,只是位填充规则不同;结果大小和原始值无直观数学对应











