如何在Python中将字节数组转换为浮点数

5
我有一个字节数组,最初是在Scala中从浮点数数组转换而来的。我需要在Python中将其转换回浮点数数组。
这是我用来在Scala中转换浮点数数组的代码:
val float_ary_len = float_ary.size
val bb = java.nio.ByteBuffer.allocate(float_ary_len * 4)
for(each_float <- float_ary){
    bb.putFloat(each_folat)
}
val bytes_ary = bb.array()

在Python中,我可以获取这个字节数组,需要将其转换回浮点数数组。
我已经尝试了以下Python代码,但它没有给我正确的浮点数。
print(list(bytes_ary[0:4]))
#['\xc2', '\xda', 't', 'Z']

struct.unpack('f', bytes_ary[0:4])
# it gave me 1.7230105268977664e+16, but it should be -109.22725 

请告诉我如何获取正确的浮点数?

3个回答

10

显然,编码该值的Scala代码使用了一种与解码它的Python代码不同的字节顺序。

请确保两个程序使用相同的字节顺序(字节序)。

在Python中,您可以通过使用>f<f而不是f来更改用于解码值的字节顺序。请参见https://docs.python.org/3/library/struct.html#struct-alignment

>>> b = b'\xc2\xdatZ'
>>> struct.unpack('f', b)   # native byte order (little-endian on my machine)
(1.7230105268977664e+16,)
>>> struct.unpack('>f', b)  # big-endian
(-109.22724914550781,)

1
从Java ByteBuffer 文档中得知:“字节缓冲区的初始顺序始终为BIG_ENDIAN。” - Mark Dickinson

1
可能是由于字节序编码的原因。您应该尝试使用大端字节序。
struct.unpack('>f', bytes_ary[0:4])

或小端:
struct.unpack('<f', bytes_ary[0:4])

0

取决于您的字节数组。

如果 print(byte_array_of_old_float) 返回 bytearray(b'684210')

那么这应该可以工作: floatvar=float(byte_array_of_old_float)

在我的情况下,字节数组来自MariaDB的select调用,并且我是这样进行转换的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接