Java 当字节数为奇数时,如何从ByteBuffer(Little Endian)获取长字节?

Java 当字节数为奇数时,如何从ByteBuffer(Little Endian)获取长字节?,java,bit-manipulation,nio,bitwise-operators,bytebuffer,Java,Bit Manipulation,Nio,Bitwise Operators,Bytebuffer,如果有1、2、4或8个字节,只需使用get()、getShort()、getInt()和getLong() 有人能帮我用逻辑得到一个长的3,5或7字节吗?我可能不得不用零来划桨。当你把一个数字换成另一个数字时,你会用符号扩展最大值位。(换句话说,如果最高阶位是1,则用1填充,如果最高阶位是0,则用0填充) 因此,在little endian中,找到最高阶位(最左边的位在最右边的字节中),然后添加一个带有FF或00的字节 例如,假设您有一个3字节的小端数字: 0000 0000 | 0000 00

如果有1、2、4或8个字节,只需使用get()、getShort()、getInt()和getLong()


有人能帮我用逻辑得到一个长的3,5或7字节吗?我可能不得不用零来划桨。

当你把一个数字换成另一个数字时,你会用符号扩展最大值位。(换句话说,如果最高阶位是1,则用1填充,如果最高阶位是0,则用0填充)

因此,在little endian中,找到最高阶位(最左边的位在最右边的字节中),然后添加一个带有FF或00的字节

例如,假设您有一个3字节的小端数字:

0000 0000 | 0000 0000 | 1000 0000
您的最高阶位是1(最后一个字节中的1),因此,4个字节中的符号扩展结果是:

0000 0000 | 0000 0000 | 1000 0000 | 1111 1111
同样,如果3字节编号为:

1111 1111 | 1111 1111 | 0101 1101
那么4字节符号扩展版本是:

1111 1111 | 1111 1111 | 0101 1101 | 0000 0000

当您将一个数字转换为另一个数字时,您将符号扩展最大值位。(换句话说,如果最高阶位是1,则用1填充,如果最高阶位是0,则用0填充)

因此,在little endian中,找到最高阶位(最左边的位在最右边的字节中),然后添加一个带有FF或00的字节

例如,假设您有一个3字节的小端数字:

0000 0000 | 0000 0000 | 1000 0000
您的最高阶位是1(最后一个字节中的1),因此,4个字节中的符号扩展结果是:

0000 0000 | 0000 0000 | 1000 0000 | 1111 1111
同样,如果3字节编号为:

1111 1111 | 1111 1111 | 0101 1101
那么4字节符号扩展版本是:

1111 1111 | 1111 1111 | 0101 1101 | 0000 0000

这个问题的答案取决于数据的字节顺序。Java的ByteBuffer类有一个order(ByteOrder)方法来设置endianness,但这对非标准长度的整型/长型值没有帮助

假设bb是ByteBuffer,length是已知的数据长度。value变量存储结果

这是一个helper函数,在下面的两个解决方案中都使用它,因为Java没有无符号数据类型(我觉得这很糟糕),所以需要它:

private static long getUnsigned(最终字节b){
if(b<0){
返回(长)b+256;
}
返回b;
}
下面是一个小小的endian解决方案:

long value = 0;
for (int shift = 0; shift < length * 8; shift += 8) {
    value |= getUnsigned(bb.get()) << shift;
}
long value = 0;
for (int i = 0; i < length; ++i) {
    value <<= 8;
    value |= getUnsigned(bb.get());
}
long值=0;
对于(int-shift=0;shiftvalue |=getUnsigned(bb.get())此问题的答案取决于数据的字节顺序。Java的ByteBuffer类有一个order(ByteOrder)方法来设置endianness,但这对非标准长度的整数值/长数值没有帮助

假设bb是ByteBuffer,length是已知的数据长度。value变量存储结果

这是一个helper函数,在下面的两个解决方案中都使用它,因为Java没有无符号数据类型(我觉得这很糟糕),所以需要它:

private static long getUnsigned(最终字节b){
if(b<0){
返回(长)b+256;
}
返回b;
}
下面是一个小小的endian解决方案:

long value = 0;
for (int shift = 0; shift < length * 8; shift += 8) {
    value |= getUnsigned(bb.get()) << shift;
}
long value = 0;
for (int i = 0; i < length; ++i) {
    value <<= 8;
    value |= getUnsigned(bb.get());
}
long值=0;
对于(int-shift=0;shiftvalue |=getUnsigned(bb.get())不想要求太多,但如何将这些字节转换为长字节?(我想我可以自己查看Java源代码并找出答案,但是如果你从你的头脑中知道这一点会很有帮助。THX!无论你需要多少字节,过程都是一样的:获取最高阶位,并对其进行扩展-这是硬件在int、short、bytes和long之间的转换方式。我不想要求太多,但是ho我要把这些字节转换成长字节吗?(我想我可以看看Java源代码,自己去找出答案,但是如果你从你的头脑中知道这一点会很有帮助。THX!不管你需要多少字节,过程都是一样的:取最高阶位,然后扩展它-这是硬件如何在整数、短字节、字节和长字节之间进行转换为什么你有短-长?协议就是这样定义的吗?只需要得到三个字节并将它们串在一起,不是吗?为什么会有短-长?协议就是这样定义的吗?只需要得到三个字节并将它们串在一起,不是吗?我有一个“大脑屁”,忘了不用getUnsigned函数,你可以改为按位和字节乘以0xFF来获得相同的分辨率我有一个“大脑放屁”,忘记了不用getUnsigned函数,而是按位和字节乘以0xFF得到相同的结果。