在 Java 中将整数转换为十六进制

Convert an int to hex in Java

我需要查明 int n 是否是 2 的幂,我的方法是将 n 转换为十六进制数并检查每一位(0 或 1)。但是,我从来没有在 Java 中使用过十六进制数字,有人可以帮我吗?

没有理由转换为十六进制来检查位。事实上,这实际上让事情变得更难了。以下行为 int 变量 "num":

生成二进制字符串
String binary = Integer.toString(num, 2)

该字符串中只有 1 和 0。然后消除任何0:

String ones = binary.replace("0", "");

如果String的长度大于1,则表示多了一位,表示它不是2的幂。如果长度为0,则表示该数没有位,表示它是 0.

转换为字符串和使用正则表达式替换都非常昂贵。

检查 2 的(正)幂的一种简单方法是检查数字位集。

if (x > 0 && Long.bitCount(x) == 1)

虽然Long.bitCount看起来很复杂,但JVM可以用一条机器码指令代替它。

测试二的幂的规范方法(在谷歌搜索如何测试二的幂时你会遇到很多,你可能会在代码中遇到它)是

x != 0 && (x & x - 1) == 0

经常遇到括号多(优先级偏执?)

x != 0 && (x & (x - 1)) == 0

通常跳过 x != 0 检查并保证零不能作为输入,或者(通常)零在某种意义上是 "as good as" 2 的幂。

如果您不想考虑 -2147483648 是 2 的幂,您当然可以将条件更改为 x > 0,尽管在许多情况下它会是(因为它与 2[=39= 一致) ]31 模 232,所以解释为无符号它是一个 PoT,无论如何它只设置了一位所以它一直是一个 PoT)


那么 x & x - 1 是怎么回事呢?它取消了最低设置位,但让我们在 PoT 的上下文中看一下它。

让我们忽略 x<2 并假设 x 的形式为 a10k(即任意位串后跟一个 1 后跟 k 个零),从中减去 1 得到a01k 因为 -1 借用所有尾随零直到它到达最低设置位,取消设置该位,然后借位消失并且最高位不变。

如果你对 a10k 和 a01k 进行按位与运算,你会得到 a00k 因为与自身相与的东西又是它自己(a),并且在尾部总是有一个 0 参与 AND 所以它都是零。

现在有两种情况。 0) a=0。然后结果为零,我们知道我们从 10k 形式的 x 开始,它是 2 的幂。并且 1) a!=0,那么结果也不为零,因为 a 仍然出现在其中,并且 x 不是 2 的幂,因为它至少有两个设置位(最低设置位我们明确地查看了 a).

中的至少一个其他地方

实际上还有两种情况被忽略了,x=0 和 x=1。如果我们允许 k 为零,则 x=1 也包括在内。 x=0 很烦人,在 x & x - 1 中有 x 作为 & 的左操作数,因此无论右操作数发生什么,结果都必须为零。所以它属于特例。