Integer.highestOneBit 返回原数二进制中最高位1对应的2的幂值(如12→8),不返回索引;输入0返回0,负数按补码处理得-2147483648;底层通过5步位或扩散+无符号右移相减实现高效提取。

它不返回最高位的位置索引,而是返回一个新整数:仅把原数二进制中**最高位的 1 保留为 1,其余所有位都置为 0**。例如 Integer.highestOneBit(12)(12 的二进制是 1100)返回 8(1000),本质是“小于等于该数的最大 2 的幂”。
核心作用:快速提取最高有效位权值
这个方法不是为了找位置,而是为了构造一个掩码或对齐基准:
- 判断是否为 2 的幂:可配合
bitCount(n) == 1使用(但更常用(n & (n - 1)) == 0 && n > 0) - 哈希表扩容时确定桶数组大小(如
HashMap内部确保容量为 2 的幂) - 计算位宽边界、做位掩码分组、树状数组中的 lowbit 辅助(常与
lowestOneBit配合) - 替代手动循环右移找最高位,性能高且无分支,适合高频调用
输入行为与边界细节
需特别注意几个实际表现:
- 输入为 0 → 返回 0(唯一合法返回 0 的情况)
-
输入为正数 → 返回对应最高位的 2 的幂,如
highestOneBit(17)→16 -
输入为负数 → 按补码解释,返回
0x80000000(即-2147483648),因为符号位是最高位;一般应避免对负数调用
底层实现:5 步“填满低位 + 减法清零”
JDK 源码精简高效,无循环无条件判断:
立即学习“Java免费学习笔记(深入)”;
public static int highestOneBit(int i) {
i |= (i >> 1);
i |= (i >> 2);
i |= (i >> 4);
i |= (i >> 8);
i |= (i >> 16);
return i - (i >>> 1);
}逻辑分两阶段:
-
“扩散填充”阶段:每次右移后与自身或运算,让最高位的 1 向低位“蔓延”。以
i = 17(00010001)为例,经 5 次操作后变为00011111(所有低位全为 1) -
“精准剥离”阶段:执行
i - (i >>> 1),相当于从全 1 区域中减去右移一位的值,自然只留下最高位那个 1(如00011111 - 00001111 = 00010000)
为什么这么设计?
该算法源自《Hacker’s Delight》图 3-1,目标是用最少指令、无分支、全位运算完成定位。相比逐位扫描或 numberOfLeadingZeros 查表,它在通用 CPU 上延迟更低、吞吐更高,且天然适配 32 位整型宽度(1+2+4+8+16=31,覆盖全部有效位)。现代 JVM 还可能进一步内联或向量化优化。


















