将5字节转换为整数

0 投票
2 回答
1434 浏览
提问于 2025-04-17 22:12

我有一些奇怪的数据,它们存储在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精确表示,所以你不会遇到任何四舍五入的错误。

撰写回答