我从ByteBuffer
读取数据,但我需要的值存储为10位。即:
1100101110 = 814
我尝试过使用BitSet
,但这会先将每个字节存储在LSB中,这会导致最后两位不正确,上面的示例变为:
1101001111 = 815
使用数字序列的示例:
8 bit 10 bit
01 02 03 04 05 06 07 08 | 09 10 | 11 12 13 14 15 16
最终会成为:
8 bit 10 bit
08 07 06 05 04 03 02 01 | 16 15 | 14 13 12 11 10 09
所以我可以按任意顺序管理第一个字节,但最后两位是从下一个字节的错误端开始的。
我目前的代码如下:
// bb stands for the ByteBuffer in use.
//length stands for the number bytes covering the 10 bit numbers
BitSet data = getBitSet(bb, length);
int totalNumbers = data.length() / 10;
int[] numbers = new int[totalNumbers];
for (int i=0; i < totalNumbers; i++){
int start = i*10;
int end = (i+1)*10;
BitSet bs = data.get(start, end);
int tenBitNumber = 0;
for (int j = bs.nextSetBit(0); j >= 0; j = bs.nextSetBit(j+1)) {
double power = pow(2, 9-j);
tenBitNumber += power;
}
numbers[i] = tenBitNumber;
}
Big Endian格式的工作示例: 字节序列:
11001011|10110111|00101100|11000111
在使用BitSet
时转换为:
11010011|11101101|00110100|11100011
什么是最好的解决方案?我需要从ByteBuffer
读取多个10位长的数字。
答案 0 :(得分:3)
首先,让我们处理五个字节(40位或4个十位数)可用的情况:将输入分成五个字节的块。每个块将产生一组四个10位数字:
int[] convertFive(byte a, byte b, byte c, byte d, byte e) {
int p = ((a & 0xff) << 2) | (b & 0xc0) >>> 6;
int q = ((b & 0x3f) << 4) | (c & 0xf0) >>> 4;
int r = ((c & 0x0f) << 6) | (d & 0xfc) >>> 2;
int s = ((d & 0x03) << 8) | (e & 0xff) >>> 0;
return new int [] { p, q, r, s };
}
将这四个int
附加到输出以生成最终结果。您可以修改方法以随时附加输出,而不是始终创建四元素数组。
以类似的方式处理少于五个字节的剩余块:两个字节变为一个10位数,三个字节变为两个数,四个字节变为三个数。如果余数为一个字节长,则输入无效。