在 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
作为 &
的左操作数,因此无论右操作数发生什么,结果都必须为零。所以它属于特例。
我需要查明 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
作为 &
的左操作数,因此无论右操作数发生什么,结果都必须为零。所以它属于特例。