我在Java程序中使用了一些长值作为位图。到目前为止,这是我的方法:
public class BitmapUtil
{
private static final long _B_MASK_LEFT_ON = 0x8000000000000000L;
public static long setNthMsb(int n)
{
return BitmapUtil._B_MASK_LEFT_ON >>> n;
}
public static boolean isNthMsbSet(long b, int n)
{
return (b & (BitmapUtil.setNthMsb(n))) != 0L;
}
public static int getNthMsbPosition(long b, int n)
{
int ix = 0;
while (ix < 64 && n >= 0) {
if (BitmapUtil.isNthMsbSet(b, ix)) {
if (n == 0) {
return ix;
} else {
n--;
}
}
ix++;
}
return -1;
}
}
我已经看到了这么多聪明的小技巧,我忍不住觉得应该有更好的方法。有吗?
答案 0 :(得分:1)
以下是几种不同的快速算法:bit hacks,寻找计算数字的log 2。
最美的是这个,但它只适用于32位数字:
unsigned int v; // find the log base 2 of 32-bit v
int r; // result goes here
static const int MultiplyDeBruijnBitPosition[32] =
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8,
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
v |= v >> 1; // first round down to power of 2
v |= v >> 2;
v |= v >> 4;
v |= v >> 8;
v |= v >> 16;
v = (v >> 1) + 1;
r = MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x077CB531U) >> 27];
答案 1 :(得分:1)
我认为这就是你想要的,没有关于效率的线索。
// long val = 0xAF00000000000000L;
long val = 0x0000000000000001L;
int n = 2;
int count = 0;
int i = 0;
while (i < 65 && count < n) {
if ((val & 0x8000000000000000L) != 0) {
count++;
}
val = val << 1;
i++;
}
这似乎从左边开始计算,其中MSB是位置1而LSB是位置64.如果i == 65,则没有设置n位。
答案 2 :(得分:0)
我在C ++中发现了32位,可以很容易地适应Java和Java。 64位
http://lsjandysf.spaces.live.com/blog/cns!54FF19028BDE00EA!440.entry