将5字节转换为整数
我有一些奇怪的数据,它们存储在5个字节里,我需要把它们转换成一个整数,这样处理起来会更方便。我手头有一些Python代码(是别人给我的),可以做到这一点,但我现在需要在Java中找到一个解决方案。我觉得我的问题在于Python和Java在存储字节的方式上有区别。
Python(我98%确定这个代码是正确的):
def bin5(b,k):
""" Returns binary integer from bytes k,k+1,...,k+4 in b."""
b0 = b[k ]
b1 = b[k+1]
b2 = b[k+2]
b3 = b[k+3]
b4 = b[k+4]
if b0<0: b0 += 256
if b1<0: b1 += 256
if b2<0: b2 += 256
if b3<0: b3 += 256
if b4<0: b4 += 256
return b0*65536.0+b1*256.0+b2+b3/256.0+b4/65536.0
Java尝试:
// Returns binary integer from bytes k,k+1,...,k+4 in b.
private static int bin5(byte[] b, int k) {
byte b0 = b[k];
byte b1 = b[k + 1];
byte b2 = b[k + 2];
byte b3 = b[k + 3];
byte b4 = b[k + 4];
return (int)(b0 * 65536.0 + b1 * 256.0 + b2 + b3 / 256.0 + b4 / 65536.0);
}
我确信问题出在Java代码的最后一个返回语句上。此外,它对某些字节数组有效,但对其他的却不行。我找不到这种行为的原因。
补充说明:举个例子:如果Python代码读取的字节是:0 11 -72 0 0
(分别对应b0到b5),它会把-72
转换成184
,然后根据上面的公式计算出值3000.0
。根据调查/数据参数,这个值是正确的。
我的直觉告诉我,Python代码在某些值上是有问题的。比如,当它读取的值是0 -127 -66 0 0
(分别对应b0到b5)时,会变成:0 129 190 0 0
,然后转换出的值是33214
。根据调查/数据参数,这个结果是不可能的。不过,也有可能这是一个错误的数据点。
补充说明2:0 13 9 0 0
应该返回3337(在Python代码中确实返回这个值)。但是在Java中,它返回的是3593。
2 个回答
0
这段代码很奇怪,它根本不返回一个整数,而是返回一个浮点数...
不过,跟这段Python代码相对应的Java代码大概是这样的(注意:完全没有进行边界检查哦):
private static double bin5(final byte[] b, final int k)
{
final ByteBuffer buf = ByteBuffer.allocate(8);
buf.position(3);
buf.put(b, k, 5);
buf.rewind();
final long l = buf.getLong();
return (double) l / 65536.0;
}
编辑:如果字节数组中偏移量k
的最后两个元素总是0(看起来确实是这样),那么你可以把从buf.rewind()
开始的部分替换成:
buf.position(2);
return (double) buf.getInt();
2
你可以这样做:
private static double bin5(byte[] b, int k) {
int b0 = b[k] & 0xFF; // treat as unsigned byte
int b1 = b[k + 1] & 0xFF;
int b2 = b[k + 2] & 0xFF;
int b3 = b[k + 3] & 0xFF;
int b4 = b[k + 4] & 0xFF;
return (b0 * 65536 + b1 * 256 + b2 + b3 / 256.0 + b4 / 65536.0);
}
因为2的幂可以用double
精确表示,所以你不会遇到任何四舍五入的错误。