11

我需要从长值中提取某些位范围,例如:

long input = 15367 (11110000000111)

然后我需要做的是从原始长中提取两个长值,

First long is 5 bits starting from bit 0, so bits 0:4 = 7 (0111)
Second long is 56 bits starting from bit 8, so bits 7:55 = 60 (1111000)

我知道这可以通过位移和屏蔽来完成,但是我不完全确定如何实现它,所以它每次都是动态的,因为每次我需要这样做时,long 会有所不同,具体的也会有所不同位范围。

我一直在阅读有关 BitSets 和 BitArrays 的信息,但我并不完全确定这些是否适合这项工作。

任何关于实现这一点的最佳方法的建议将不胜感激。

谢谢!

4

2 回答 2

13

要提取nrBits从 offset 开始的位offset,您可以执行以下操作:

public static long extractSub(final long l, final int nrBits, final int offset)
{
    final long rightShifted = l >>> offset;
    final long mask = (1L << nrBits) - 1L;
    return rightShifted & mask;
}

注意>>>右移运算符的用户;这样你就不用随身携带标志位了。

至于(1L << nrBits) - 1L,就是2^nrBits - 1L就是要有long常数。

另请注意,没有“边界检查”(例如,偏移量或位数大于 63 或负数)。

于 2013-08-06T14:32:18.727 回答
2

要提取位 x 和位 y 之间的位,其中 x 是两个数字中的较大者,您可以说

long mask = (Math.pow(2,x+1)-1)- (Math.pow(2,y+1)-1);
long extract = input & mask;
于 2013-08-06T14:40:10.937 回答