【问题标题】:Converting 5 bytes to an integer将 5 个字节转换为整数
【发布时间】:2014-04-18 20:34:51
【问题描述】:

我有一些奇怪的数据存储在 5 个字节中,我需要能够将其转换为 int 以便能够更轻松地对其进行操作。我已经有一些 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 代码的最后一个 return 语句中。此外,它适用于某些字节数组,但不适用于其他字节数组。我找不到这种行为的原因。

编辑:示例: 如果 Python 代码读取字节:0 11 -72 0 0 for b0 thru 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。

【问题讨论】:

  • byte 不是用 Java 签名的吗?如果是这样,你如何使用byte 来表示b0 等等,因为它们的范围从0 到255。另外,你需要去掉那些.0 ——分数加起来可以是一个整数.
  • 您遇到了什么问题? int 也不会像您期望的那样有小数。并且字节已签名,并且您缺少上面的符号转换代码。
  • 这似乎是返回一个浮点数,而不是一个整数......
  • 我认为 .0 存在所以整数除法不会发生(实际上不确定这是否是一个问题)。我对字节以及它们如何表示数字还不够熟悉。然后返回被转换为 int,所以我不认为 fge 是在正确的轨道上。编辑:丹尼尔:假设数据从 5 个字节中读取 3000,在某些情况下它将读取 3000。但是,根据字节,如果假设读取类似 3514 的内容,它将改为读取 3820。一个值那是 +256 的折扣。
  • 它在哪里转换为 int?当然不是在你目前展示的python代码中

标签: java python int type-conversion byte


【解决方案1】:

你可以的

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 精确表示,所以不会出现任何舍入错误。

【讨论】:

  • 太棒了。效果很好。谢谢你。您是否碰巧知道某些byte[]s 的python 代码是否有错误(如我第一次编辑的第二段)?
  • @voltnor 在我没有受过教育的人看来,python 看起来不错(我不知道 python)if(b&lt;0) b+=256 看起来很笨重,也许它支持像 C/Java 一样的掩码。
  • 我会调查的。 Java 代码产生相同的大值,所以它可能只是一个错误的数据点。不幸的是,我现在没有办法说出来。嘘。
【解决方案2】:

这段代码很奇怪;它根本不返回一个整数,而是一个浮点数......

无论如何,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();

【讨论】:

  • 数据具有非常特定的格式,因此边界不是问题。并返回双倍?
  • 好吧,看看原始的python代码:它确实返回一个浮点数,而不是一个整数(一个字节除以256.0得到一个浮点数)
  • 另外,这也行不通。如果字节数组表示值 3000,则返回 768000.0。不过谢谢!
  • 那么,使用示例字节数组以及如何从中提取 3000 来编辑问题;)
  • 全部用两个例子编辑。我不确定第二个应该输出什么,但应该是 3000 秒。
猜你喜欢
  • 2013-06-08
  • 2013-09-27
  • 1970-01-01
  • 2012-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
相关资源
最近更新 更多