biginteger.bitcount()统计二进制补码表示中1的个数:正数直接统计其二进制1的个数;负数按等价公式(-n-1).bitcount()计算,如-1得0、-2得1、-5得1。

BigInteger.bitCount() 统计的是该数**二进制补码表示中值为 1 的比特位个数**,也就是“汉明重量”(Hamming weight),但它对负数的处理方式与正数不同——它基于补码逻辑,而非简单看绝对值的二进制。
正数:直接统计二进制中 1 的个数
对非负整数,bitCount() 等价于统计其无符号二进制表示中 1 的个数。
-
例如:
BigInteger.valueOf(5).bitCount()→ 5 的二进制是101,结果为 2 -
BigInteger.ZERO.bitCount()→ 0 -
BigInteger.ONE.bitCount()→ 1
负数:按无限长补码形式统计
Java 中 BigInteger 是符号-幅值表示的,但 bitCount() 对负数的定义是:将该数视为用二进制补码表示的、无限长的负数,然后统计其中 1 的个数。由于补码下负数的高位全是 1,无限长补码会有无穷多个 1 —— 但这显然不可行。所以 BigInteger 实际采用等价定义:
- 对负数
n,n.bitCount() == (-n.subtract(BigInteger.ONE)).bitCount() - 即:先取反再加 1(求补码的逆操作),再统计结果的 bitCount
例如:BigInteger.valueOf(-1).bitCount()
-1 的补码(任意位宽)全是 1,但按公式:-(-1) - 1 = 1 - 1 = 0,0.bitCount() == 0 → 所以结果是 0
再如:BigInteger.valueOf(-2).bitCount()-(-2) - 1 = 2 - 1 = 1,1.bitCount() == 1 → 结果是 1
再如:BigInteger.valueOf(-3).bitCount()-(-3) - 1 = 3 - 1 = 2,2.bitCount() == 1(因为 2 是 10)→ 结果是 1
为什么这样设计?
这种定义保证了恒等式成立:n.xor(m).bitCount() == n.bitCount() ^ m.bitCount() & 1(不成立)——其实更关键的是保持与 Integer.bitCount() 在非负时行为一致,并为负数提供一个**有限、确定、有数学意义**的结果。
本质上,它等于:
负数 n 的 bitCount = 补码表示中最低有效位开始连续 0 的个数 + 1(即从最低位起第一个 1 出现的位置,再加 1?不对)—— 更准确说:它等于 ~n(按位取反)的 bitCount,其中 ~n = -n-1,而 ~n 是非负的,所以可直接算。
实用建议
- 若你只关心**绝对值的二进制中 1 的个数**,请先调用
abs():n.abs().bitCount() - 若你在做密码学或位运算分析,需严格按补码语义,请记住:负数的
bitCount()小于等于对应正数,且常比直觉少 - 可验证:
BigInteger.valueOf(-5).bitCount()→ 先算5-1=4,4.bitCount()==1→ 结果为 1
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











