Integer.lowestOneBit() 是 Java 中一个位运算相关的实用方法,用于提取整数二进制表示中最低位的 1(即最右边的 1),并将其余位清零。


方法定义

public static int lowestOneBit(int i)
  • 所属类: java.lang.Integer
  • 参数: i - 要处理的 int
  • 返回类型: int
  • 访问修饰符: public static
  • 自 JDK 版本: 1.5

功能说明

该方法返回一个整数,其二进制表示中只有原数值最低位的 1 保持为 1,其余所有位均为 0

换句话说,它提取了原数中最小的 2 的幂次因子

数学原理

利用补码特性:
lowestOneBit(i) = i & (-i)

  • -ii 的补码(按位取反 + 1)
  • i & (-i) 正好保留了最右边的 1,其余位变为 0

示例代码

1. 基本用法

System.out.println(Integer.lowestOneBit(6));   // 输出: 2
// 6 的二进制: 110 → 最低位的 1 是 10₂ = 2

System.out.println(Integer.lowestOneBit(12));  // 输出: 4
// 12 的二进制: 1100 → 最低位的 1 是 100₂ = 4

System.out.println(Integer.lowestOneBit(7));   // 输出: 1
// 7 的二进制: 111 → 最低位的 1 是 1₂ = 1

2. 2 的幂次方数

System.out.println(Integer.lowestOneBit(8));   // 输出: 8
// 8 的二进制: 1000 → 本身就是 2 的幂,返回自身

System.out.println(Integer.lowestOneBit(16));  // 输出: 16

3. 奇数

System.out.println(Integer.lowestOneBit(15));  // 输出: 1
// 15 的二进制: 1111 → 最低位是 1

System.out.println(Integer.lowestOneBit(21));  // 输出: 1
// 21 的二进制: 10101 → 最低位是 1

4. 特殊值

System.out.println(Integer.lowestOneBit(0));   // 输出: 0
// 0 没有 1,返回 0

System.out.println(Integer.lowestOneBit(-8));  // 输出: 8
// 负数使用补码:-8 的二进制表示中最低位 1 对应 +8

使用技巧

1. 判断是否为 2 的幂

public static boolean isPowerOfTwo(int n) {
    return n > 0 && Integer.lowestOneBit(n) == n;
}

System.out.println(isPowerOfTwo(8));  // true
System.out.println(isPowerOfTwo(6));  // false

2. 提取二进制中最低位 1 的位置

public static int getLowestBitPosition(int n) {
    if (n == 0) return -1;
    int lowestBit = Integer.lowestOneBit(n);
    return Integer.numberOfTrailingZeros(lowestBit);
}

System.out.println(getLowestBitPosition(12)); // 输出: 2 (1100, 从右数第 2 位)

3. 清除最低位的 1

// 清除最低位的 1:i - lowestOneBit(i)
int original = 12; // 1100
int cleared = original - Integer.lowestOneBit(original); // 1100 - 100 = 1000
System.out.println(cleared); // 输出: 8

4. 遍历所有为 1 的位

int n = 13; // 1101
while (n != 0) {
    int lowestBit = Integer.lowestOneBit(n);
    System.out.println("Found bit: " + lowestBit);
    n -= lowestBit; // 清除最低位的 1
}
// 输出: 1, 4, 8

常见错误

❌ 1. 误解返回值含义

// 错误理解:认为返回最低位的值(0 或 1)
int result = Integer.lowestOneBit(6); 
// 期望 0?实际返回 2!

❌ 2. 忽视 0 的特殊情况

// 需要特殊处理 0
if (n != 0) {
    int bit = Integer.lowestOneBit(n);
    // 处理 bit
}

❌ 3. 与 highestOneBit() 混淆

System.out.println(Integer.lowestOneBit(12));  // 4  (100)
System.out.println(Integer.highestOneBit(12)); // 8  (1000)

注意事项

  1. 返回的是值,不是位置:返回的是包含最低位 1 的完整数值,不是位索引。

  2. ⚠️ 0 的处理:输入 0 时返回 0,因为没有 1 可提取。

  3. 🔢 负数处理:负数使用补码表示,方法仍能正确提取最低位的 1(对应正数值)。

  4. 🔄 幂次特性:对于 2 的幂次方数,lowestOneBit(n) == n

  5. 💡 性能优秀:内部实现高效,通常编译为少量机器指令。


最佳实践与性能优化

1. ✅ 用于位操作算法

在处理位掩码、状态标志、位图等场景非常有用:

// 检查某个标志是否设置(且是最低设置位)
if (flags != 0 && Integer.lowestOneBit(flags) == TARGET_FLAG) {
    // 处理逻辑
}

2. ✅ 替代手动位运算

// 推荐
int lowest = Integer.lowestOneBit(n);

// 不推荐(易错)
// int lowest = n & (~n + 1); // 虽然等价,但可读性差

3. ✅ 与 Integer.bitCount() 配合使用

// 检查是否只有一个位被设置(即是否为 2 的幂)
boolean isSingleBit = Integer.bitCount(n) == 1;
// 或使用 lowestOneBit
boolean isPowerOfTwo = n > 0 && Integer.lowestOneBit(n) == n;

4. ✅ 在集合遍历中优化

// 位图遍历优化
int bitmap = 0b1101;
while (bitmap != 0) {
    int lowest = Integer.lowestOneBit(bitmap);
    processBit(lowest);
    bitmap ^= lowest; // 清除该位
}

总结

项目 说明
核心功能 提取整数二进制表示中最低位的 1
返回值 一个 2 的幂次方数(或 0)
关键公式 i & (-i)
典型用途 位操作、2 的幂判断、位遍历优化
性能 极高,常数时间复杂度 O(1)

📌 一句话总结

Integer.lowestOneBit(i) 是一个高效的位操作工具,它利用补码特性 i & (-i) 快速提取整数中最低位的 1,返回对应的 2 的幂次值,是处理二进制位模式的利器。

在算法竞赛、底层系统编程、位图操作等需要高效位运算的场景中,lowestOneBit() 是一个不可或缺的工具方法。掌握它不仅能提升代码效率,还能加深对二进制和补码的理解。