如何将四个有符号浮点数打包成一个整数?

Den*_*nko 1 python bit-manipulation packing python-3.5

我需要能够将 4 个浮点数字打包成一个整数,然后将该整数解包到我的 4 个浮点数中。

浮点数示例(精度不超过8位):

-0.02513393, -0.02394553, 0.04248389, 0.02388026
Run Code Online (Sandbox Code Playgroud)

所以,我想首先我需要将这些浮点数乘以 1000000000,将其转换为整数。

floats = [-0.02513393, -0.02394553, 0.04248389, 0.02388026]
integers = list(map(lambda i: int(i * 1000000000), floats))
# output: [-25133930, -23945530, 42483890, 23880260]
Run Code Online (Sandbox Code Playgroud)

然后使用按位运算将四个数字合为一个,如下所示:

a, b, c, d = integers
packed = (a << 24) | (b << 16) | (c << 8) | d
Run Code Online (Sandbox Code Playgroud)

但是,这似乎不对,因为我尝试打包的值已签名。


您能否提示我将此类带符号浮点数打包为单个整数的正确解决方案以及解包它们的正确方法?


我想添加1到每个负值的末尾和0每个正值的末尾,并将整数恢复为浮点数,我首先检查是否有一个1我会否定该值,然后除以 1000000000。但这并不优雅全部。

unu*_*tbu 5

使用 NumPy,您可以dtype 的 4 元素数组float16视为 dtype 的整数数组int64

In [125]: np.array([-0.02513393, -0.02394553, 0.04248389, 0.02388026], dtype=np.float16).view(np.int64)
Out[125]: array([2746396911566169711])
Run Code Online (Sandbox Code Playgroud)

要解压 int 你可以使用view(np.float16)

In [126]: np.array([2746396911566169711]).view(np.float16)
Out[126]: array([-0.02513123, -0.02394104,  0.04248047,  0.02388   ], dtype=float16)
Run Code Online (Sandbox Code Playgroud)

请注意,精度会有所损失。


使用Python3.2(或更高版本)并且不使用NumPy,您可以将浮点数打包为字节,然后用于int.from_bytes将字节转换为int。要解压,请使用int.to_bytesstruct.unpack

import struct

def floats_to_int(floats):
    return int.from_bytes(struct.pack('4d', *floats), 'big')

def int_to_floats(packed):
    return struct.unpack('4d', packed.to_bytes(4*8, 'big'))

floats = [-0.02513393, -0.02394553, 0.04248389, 0.02388026]
print(floats)
packed = floats_to_int(floats)
print(packed)
result = int_to_floats(packed)
print(result)
Run Code Online (Sandbox Code Playgroud)

印刷

[-0.02513393, -0.02394553, 0.04248389, 0.02388026]
3995686615650679380069295189325600154682811585786433559914521688689786263615
(-0.02513393, -0.02394553, 0.04248389, 0.02388026)
Run Code Online (Sandbox Code Playgroud)