如果您有二进制数10110,我怎么能让它返回5?例如,一个数字,告诉我们使用了多少位?下面列出了一些类似的例子:
如何以最简单的方式获得Java?我提出了以下方法,但我可以更快地完成:
public static int getBitLength(int value)
{
if (value == 0)
{
return 0;
}
int l = 1;
if (value >>> 16 > 0) { value >>= 16; l += 16; }
if (value >>> 8 > 0) { value >>= 8; l += 8; }
if (value >>> 4 > 0) { value >>= 4; l += 4; }
if (value >>> 2 > 0) { value >>= 2; l += 2; }
if (value >>> 1 > 0) { value >>= 1; l += 1; }
return l;
}
答案 0 :(得分:11)
最简单?
32 - Integer.numberOfLeadingZeros(value)
如果您正在寻找算法,Java API的实现者会同意您的分而治之的位移方法:
public static int numberOfLeadingZeros(int i) {
if (i == 0)
return 32;
int n = 1;
if (i >>> 16 == 0) { n += 16; i <<= 16; }
if (i >>> 24 == 0) { n += 8; i <<= 8; }
if (i >>> 28 == 0) { n += 4; i <<= 4; }
if (i >>> 30 == 0) { n += 2; i <<= 2; }
n -= i >>> 31;
return n;
}
编辑:提醒那些信任浮点计算准确性的人,请运行以下测试工具:
public static void main(String[] args) {
for (int i = 0; i < 64; i++) {
long x = 1L << i;
check(x);
check(x-1);
}
}
static void check(long x) {
int correct = 64 - Long.numberOfLeadingZeros(x);
int floated = (int) (1 + Math.floor(Math.log(x) / Math.log(2)));
if (floated != correct) {
System.out.println(Long.toString(x, 16) + " " + correct + " " + floated);
}
}
第一个检测到的偏差是:
ffffffffffff 48 49
答案 1 :(得分:6)
不幸的是,没有Integer.bitLength()
方法直接为您提供答案。
BigInteger
存在类似的方法,因此您可以使用该方法:
BigInteger.valueOf(value).bitLength()
构造BigInteger
对象会降低效率,但这只会影响数百万次。
答案 2 :(得分:2)
您想要计算数字的基数2对数 - 具体来说:
1 + floor(log2(value))
Java有一个使用base e的Math.log方法,所以你可以这样做:
1 + Math.floor(Math.log(value) / Math.log(2))
答案 3 :(得分:1)
要小心你所要求的。一种非常快速的技术是进行表查找:
int bittable [] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, ... };
int numbits (int v)
{
return bittable [v];
}
其中bittable
包含每个int的条目。当然,这会带来负面价值的复杂性。更实际的方法是计算数字
int bittable [16] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
int numbits (int v)
{
int s = 0;
while (v != 0)
{
s += bittable [v & 15];
v >>= 4;
}
return s;
}
答案 4 :(得分:1)
您真的只想找到最高位的位置1.请参阅this page,标题为“查找整数的整数对数基数2(也就是最高位集的位置)”
答案 5 :(得分:1)
从here开始,只需按位和添加即可:
int GetHighestBitPosition(int value) {
if (value == 0) return 0;
int position = 1;
if ((value & 0xFFFF0000) == 0) position += 16;
if ((value & 0xFF00FF00) == 0) position += 8;
if ((value & 0xF0F0F0F0) == 0) position += 4;
if ((value & 0xCCCCCCCC) == 0) position += 2;
if ((value & 0xAAAAAAAA) == 0) position += 1;
return position;
}
答案 6 :(得分:0)
我认为该数字的四舍五入的log_2将为您提供所需的内容。
类似的东西:
return (int)(Math.log(value) / Math.log(2)) + 1;
答案 7 :(得分:0)
int CountBits(uint value)
{
for (byte i = 32; i > 0; i--)
{
var b = (uint)1 << (i - 1);
if ((value & b) == b)
return i;
}
return 0;
}
答案 8 :(得分:0)
如果您正在寻找最快的(并且没有桌子,这当然更快),这可能就是那个:
public static int bitLength(int i) {
int len = 0;
while (i != 0) {
len += (i & 1);
i >>>= 1;
}
return len;
}
答案 9 :(得分:0)
Integer.toBinaryString(值)。长度()
答案 10 :(得分:0)
另一种解决方案是根据API
使用length()
的{{1}}
返回“逻辑大小”...索引 最高设置位...加一。
要使用BitSet
,您需要创建一个数组。所以它并不像从纯BitSet
开始那么简单。但是你从JDK盒中得到它 - 经过测试和支持。它看起来像这样:
int
应用于问题中的示例:
public static int bitsCount(int i) {
return BitSet.valueOf(new long[] { i }).length();
}
在询问位时,我认为 bitsCount(0b101); // 3
bitsCount(0b000000011); // 2
bitsCount(0b11100); // 5
bitsCount(0b101010101); // 9
是适当的数据结构。