2014-03-13 204 views
0

我有一些奇怪的数据存储在5个字节中,我需要能够将其转换为int以便能够更容易地操作它。我有一些Python代码(提供给我的)已经这样做了,但我需要能够在Java中有一个解决方案。我认为我的问题是Python和Java在存储字节的方式上有所不同。将5个字节转换为整数

的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为B0通B5尊称,它会改变-72184,然后计算基于上述公式的值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.

+0

Java中没有'byte'签名吗?如果是这样,你怎么能用'byte'来表示'b0'等等,因为它们的范围是从0到255。另外,你需要去掉那些'.0' - 分数可以加起来整数。 –

+0

你看到什么问题? int也不会像你期待的那样有小数。并且字节被签名,并且您缺少上述的符号转换代码。 –

+1

这似乎是返回一个浮点数,而不是一个int ... – fge

回答

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表示,因此不会有任何舍入误差。

+0

这很漂亮。很棒。谢谢。如果Python代码对某些byte [](如我的第一次编辑的第二段)错误,您是否碰巧有任何见解? – voltnor

+0

@voltnor python看起来没问题(我不知道python)if(b <0)b + = 256'看起来很笨,也许它支持像C/Java这样的屏蔽。 –

+0

我会研究它。 Java代码产生相同的大值,所以也许它只是一个不好的数据点。不幸的是,我现在没有办法。哪里哪里。 – voltnor

0

此代码很奇怪;它不会在所有,但一个float返回一个整数...

无论如何,相当于Java的Python代码的是这样的(注:在没有边界检查是在所有做):

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(); 
+0

数据具有非常特定的格式,因此边界不是问题。并返回一个双? – voltnor

+0

那么,看看原来的python代码:它_does_返回一个浮点数,而不是一个int(除以256.0的字节给出一个浮点数) – fge

+0

此外,这是行不通的。如果字节数组表示值3000,则返回768000.0。谢谢你! – voltnor