更多Pythonic方式将24位整数转换为32位整数

时间:2018-03-08 22:24:39

标签: python binary type-conversion

我目前使用以下代码将表示小端符号24位整数的字节数组转换为带符号的32位整数列表。

xs = list(bytes_object)
ys = [xs[x:x+3] + [255] if xs[x+2] & 128 else xs[x:x+3] + [0]
      for x in range(0, len(xs), 3)]
int32s = [struct.unpack('<i', bytes(y))[0] for y in ys]

是否有更多的pythonic或有效方法来处理转换?

3 个答案:

答案 0 :(得分:1)

在numpy之外,这是非常pythonic:

bytes_object = b'\x01\x00\x00\x00\x00\xf0'
[int.from_bytes(bytes_object[x:x+3], byteorder='little', signed=True) for x in range(0, len(bytes_object), 3)]

答案 1 :(得分:0)

在我的头脑中,有这样的事情:

import numpy as np

# First convert the buffer to an array of 3-vectors of uint8s
a3 = np.frombuffer(x, dtype=np.uint8).reshape(-1, 3)

# Now sign-extend it to an array of 4-vectors of uint8s
signs = (a3[..., 0] > 0x80) * 0xFF
a4 = np.concatenate((signs.reshape(-1, 1), a), axis=1)

# Now convert that to an array of int32s
i = a4.view(np.int32)

# And what you eventually wanted to do was convert to float64?
f = i.astype(np.float64)

我确定我至少犯了一个错误(至少这肯定不会在大端系统上工作),而且我没有电脑numpy安装在我面前,但希望这能让你开始。无需在Python循环中执行任何操作。

答案 2 :(得分:0)

这是我的解决方案。 -8388608 -> FF80 0000(32bit) 或 FFFF FFFF FF80 0000(64bit) 可以转换有符号值。

test_bytes = b'\x58\x18\x85'
def byte3toint(tmp, signed=True):
    b = tmp[0] | tmp[1] << 8 | tmp[2] << 16 # restore the bit represention
    if signed and tmp[2] & 128:
        b |= -8388608
    return b
assert byte3toint(test_bytes) == int.from_bytes(test_bytes, 'little', signed=True)