【问题标题】:Converting a float to bytearray将浮点数转换为字节数组
【发布时间】:2016-08-21 22:49:18
【问题描述】:

所以,我想要做的是将浮点数转换为字节数组,但我一直没有收到任何输入,而且我的计算机极度减慢/冻结。 我的代码是

import struct

def float_to_hex(f):
    return hex(struct.unpack('<I', struct.pack('<f', f))[0])
value = 5.1 #example value
...
value = bytearray(int(float_to_hex(float(value)), 16)

我在另一篇文章中发现了一个将浮点数转换为十六进制的函数

def float_to_hex(f):
    return hex(struct.unpack('<I', struct.pack('<f', f))[0])

然后我将它从十六进制转换为整数。 这有什么问题?我怎样才能更好地将它从浮点数转换为 bin 或 bytearray?

【问题讨论】:

  • 为什么要将浮点数作为字节数组?你想达到什么目的?
  • 这是将浮点数的二进制形式显示为十六进制文本,还是获取原始字节?使用hex 意味着您需要十六进制文本,而不是原始字节,在这种情况下,您根本不需要bytearray(这是一种二进制数据类型),您需要str(文本输入 Python 3)。
  • 另外,你真的想要 C float 或 C double 代表吗?
  • 我正在寻找的是获取原始字节。我在寻找一种从浮点数中以十六进制表示 IEEE (754) 浮点数的方法时得到了这个函数。我知道如果我可以将十六进制字符串插入gregstoll.dyndns.org/~gregstoll/floattohex 并获得原始数字,那将是正确的。
  • @tatatat0:如果你在网页上输入这个,你不想要原始字节,你想要所述字节的十六进制表示;我无法访问该站点(代理阻止它),但网络表单通常不接受原始二进制数据的输入,它们采用十六进制编码版本。作为记录,Python 的 float 类型实际上是基于 C double 类型,而不是 C float 类型(通常是 double 精度的一半),因此您可能需要格式代码 d,不是f。正如我在另一条评论中提到的那样,在 3.5 上,struct.pack("f", value).hex() 应该会为您提供所需的十六进制文本。

标签: python python-3.x


【解决方案1】:

这取决于你想要什么,以及你打算用它做什么。如果你想要的只是一个字节数组,那么:

import struct

value = 5.1

ba = bytearray(struct.pack("f", value))  

ba 是一个字节数组。但是,如果您希望显示十六进制值(我怀疑),那么:

print([ "0x%02x" % b for b in ba ])

编辑

这给出(对于值 5.1):

['0x33', '0x33', '0xa3', '0x40']

但是,CPython 使用 C 类型 double 来存储甚至很小的浮点数(这是有充分理由的),所以:

value = 5.1
ba = bytearray(struct.pack("d", value))   
print([ "0x%02x" % b for b in ba ])

给予:

['0x66', '0x66', '0x66', '0x66', '0x66', '0x66', '0x14', '0x40']

【讨论】:

  • 格式化十六进制的更好/更快的方法(删除0x并将其保留为单个十六进制字符串)将是struct.pack("f", value).hex()(需要3.5+,但会产生str用于直接输出)或binascii.hexlify(struct.pack("f", value))(适用于任何Python版本,但返回bytes对象;需要解码为ascii才能得到str,例如binascii.hexlify(struct.pack("f", value)).decode('ascii'))。但如果目标只是一个bytearray,未格式化,那么是的,你所拥有的就是显而易见的方式。
  • @ShadowRanger:很好的建议,我尽量保持简单,因为我发现要求含糊。
  • 注意:binascii.hexlify() 也适用于 bytearray()
  • 我希望从 5.1 得到的结果是 0x40 a3 33 33 或 64 163 51 51。不是字符串。我只想查看用于调试的字符串。你的第一个答案似乎是正确的。为什么我最初的解决方案如此密集,没有回报?
  • 当你像你一样大量嵌套函数调用时,这就是问题 - 它们是调试的猪。密集是因为您输入bytearray() 的数字很大:在5.1 的示例中为1084437299。您没有将该数字转换为字节,您正在创建一个 该大小 的字节数组:“如果它是一个整数,则该数组将具有该大小并将使用空字节进行初始化。 "docs.python.org/3.1/library/functions.html#bytearray
【解决方案2】:

我希望从 5.1 得到的结果是 0x40 a3 33 33 或 64 163 51 51。不是字符串。

从浮点数中获取所需的整数列表:

>>> import struct
>>> list(struct.pack("!f", 5.1))
[64, 163, 51, 51]

或与bytearray 类型相同:

>>> bytearray(struct.pack("!f", 5.1))
bytearray(b'@\xa333')

注意:字节串(bytes 类型)包含完全相同的字节:

>>> struct.pack("!f", 5.1)
b'@\xa333'
>>> for byte in struct.pack("!f", 5.1):
...    print(byte)
...
64
163
51
51

区别仅在于可变性。 listbytearray 是可变序列,而 bytes 类型表示不可变的字节序列。否则,bytesbytearray 类型具有非常相似的 API。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-09-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多