用JAVA编写位读取器(32位低位从高位到低位打包)

用JAVA编写位读取器(32位低位从高位到低位打包),java,bit-manipulation,endianness,Java,Bit Manipulation,Endianness,不管我如何翻来覆去地处理字节和位,我都无法让它工作。我对endianess非常了解,在某种程度上理解MSB(最高有效位)。但我似乎无法将两者结合起来 目前,我有一个普通JAVA字节[]数组中的数据。位流中的符号使用32位小尾端最高到最低有效位打包进行编码。我需要用一种读位器每次读N位,就像: 公共整数读取(整数位,布尔高级读取器) 当然,要跟踪 private int byteOffset; private int bitOffset; 问题是将值作为整数获取,我无法理解如何正确实现:( 编辑

不管我如何翻来覆去地处理字节和位,我都无法让它工作。我对endianess非常了解,在某种程度上理解MSB(最高有效位)。但我似乎无法将两者结合起来

目前,我有一个普通JAVA字节[]数组中的数据。位流中的符号使用32位小尾端最高到最低有效位打包进行编码。我需要用一种读位器每次读N位,就像:

公共整数读取(整数位,布尔高级读取器)

当然,要跟踪

private int byteOffset;
private int bitOffset;
问题是将值作为整数获取,我无法理解如何正确实现:(

编辑:我正在尝试使用这个Apache许可的BitReader类,该类添加了little endian(我添加到readInt())支持(原始代码:):

Luku==-1510145665,我认为应该是-1510145696

47, -91, 52, -12 to little endian int => 11110100001101001010010100101111
2, -6, 11, -24 to little endian int => 11101000000010111111101000000010
在消耗21位后,以下32位
101001011111010000000101111111
以十六进制表示为
0xA5FD017F
,以十进制表示为
2784821631

System.out.println(0xA5FD017F);
long l = 2784821631L;
System.out.println((int)l);
都会给你-1510145665。所以原始代码是正确的


当一次读取少于32位时,将输入字节数组设置为little endian的更改可能不是您想要的。您可能必须一次读取一个字节,而不是使用现有的readInt()

看看
java.nio.ByteBuffer
及其字节排序功能。是的,这很简单,只需进行排序。没有问题。之前我尝试将数组作为ByteBuffer传递,并将排序集传递给位读取器,通过以正确的尾数从整个字节开始读取整数来推进每个字节的读取器。但是但我仍然无法正确提取位。你能给我们看一些代码,让我们看看你的问题是什么吗?访问位和访问字节没什么不同。你不需要所有这些。你养着一条狗,自己在叫。只需将正确的字节顺序设置为
ByteBuffer
,然后调用
ByteBuffer.readInt()
。两行代码。请提供一些显示您描述的顺序的数据,以及正确解码后的值。事实上,我只是在ReadInt中保留了原始的位播放,以防它比ReadInt()更快等从缓冲区。可能是原作者这样做的原因。谢谢,我现在也相信这是正确的行为。问题实际上似乎在检查*方法中:它们应该读取位而不前进,但在使用little endian时无法正确“重置”进度。
47, -91, 52, -12 to little endian int => 11110100001101001010010100101111
2, -6, 11, -24 to little endian int => 11101000000010111111101000000010
System.out.println(0xA5FD017F);
long l = 2784821631L;
System.out.println((int)l);