Python输出奇怪的bytearray

问题描述 投票:1回答:3

Python有时会产生奇怪的神秘字节数组。我不知道如何解释它们。

请考虑以下示例。

import struct
floats = [3.14, 2.7, 0.0, -1.0, 1.1]
s = struct.pack('f'*len(floats), *floats)
print("The bytes:")
print(s)

struct.pack函数应该输出列表中每个值的'bytes-representation'。该列表由64位浮点数组成(我的计算机是64位),所以我希望每个浮点数由8个字节表示:

 3.14 -> 0x40 0x09 0x1E 0xB8 0x51 0xEB 0x85 0x1F
 2.7  -> 0x40 0x05 0x99 0x99 0x99 0x99 0x99 0x9A
 0.0  -> 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00
-1.0  -> 0xBF 0xF0 0x00 0x00 0x00 0x00 0x00 0x00
 1.1  -> 0x3F 0xF1 0x99 0x99 0x99 0x99 0x99 0x9A

顺便说一下,我使用以下网站进行了正确的转换:http://babbage.cs.qc.cuny.edu/IEEE-754.old/Decimal.html

不幸的是,Python没有输出我期望的那些字节。相反,Python会输出一些非常神秘的字节列表。但这真的是一个字节列表吗? Python输出的东西很奇怪:

b'\xc3\xf5H@\xcd\xcc,@\x00\x00\x00\x00\x00\x00\x80\xbf\xcd\xcc\x8c?'

请帮助我理解Python在这里做了什么。

编辑

显然我应该使用'd'而不是'f',因为我在我的机器上使用双精度浮点数。谢谢先生。 Rad雷克萨斯为您的答案。但我仍然对Python输出感到有些困惑。让我澄清一下。

我从您给我的以下代码开始:

import struct
floats = [3.14, 2.7, 0.0, -1.0, 1.1]
s = []
for f in floats:
    s.append(struct.pack('d', f))

在继续之前,我检查对象s以掌握正在发生的事情。这是我从s得到的:

>>> s
[ b'\x1f\x85\xebQ\xb8\x1e\t@', 
  b'\x9a\x99\x99\x99\x99\x99\x05@',
  b'\x00\x00\x00\x00\x00\x00\x00\x00', 
  b'\x00\x00\x00\x00\x00\x00\xf0\xbf',
  b'\x9a\x99\x99\x99\x99\x99\xf1?'     ]

s中的一些条目长度为8个字节。这就是我所期待的。但有些参赛作品更短。无论如何,没有条目给出相应浮点数的正确8字节表示 - 浮点数0.0除外。

您的代码继续使用一些魔法来提取每个浮点数实际正确的8个字节:

print("The bytes:")
for floatInHex in s:
    for byteval in floatInHex:
        print ('%02x' % byteval, end="")

现在我们得到了正确的结果。但是为什么s对象尚未包含每个浮点数正确的8字节,首先?为什么需要这种额外的魔力?

python python-3.x double bytearray
3个回答
2
投票

binascii.hexlify

>>> binascii.hexlify(struct.pack('>d', floats[0]))
b'40091eb851eb851f'

如果要分别获取每个浮点表示,则需要迭代它们并转换它们。 (使用循环或列表理解,..)

>>> import struct
>>> import binascii
>>>
>>> floats = [3.14, 2.7, 0.0, -1.0, 1.1]
>>> s = struct.pack('>' + 'd'*len(floats), *floats)
>>> binascii.hexlify(s)
b'40091eb851eb851f400599999999999a0000000000000000bff00000000000003ff199999999999a'

1
投票

你想解压缩为>>> for f in floats: ... print(' '.join('0x{:02x}'.format(c) for c in struct.pack('>d', f))) ... 0x40 0x09 0x1e 0xb8 0x51 0xeb 0x85 0x1f 0x40 0x05 0x99 0x99 0x99 0x99 0x99 0x9a 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0x00 0xbf 0xf0 0x00 0x00 0x00 0x00 0x00 0x00 0x3f 0xf1 0x99 0x99 0x99 0x99 0x99 0x9a ,但在程序中你使用double的说明符:float。这就是你得到的:

f

(请参阅c3 f5 48 40 for 3.14 ,了解为什么会看到一些ASCII字符。)

此代码将为每个数字打印出一行十六进制:

python struct pack double

结果:

import struct
floats = [3.14, 2.7, 0.0, -1.0, 1.1]
s = []
for f in floats:
    s.append(struct.pack('d', f))
print("The bytes:")
for floatInHex in s:
  for byteval in floatInHex:
    print ('%02x' % byteval, end=""),
  print ()

0
投票

Python在打印时输出“奇怪”行为,因为The bytes: 1f85eb51b81e0940 9a99999999990540 0000000000000000 000000000000f0bf 9a9999999999f13f 函数将尝试将任何ASCII可打印字符打印为ASCII,而不是十六进制。

它使用print正确打印,因为它从不打印ASCII字符,只打印十六进制字符。

让我上当了!即将问同样的问题,然后在这里找到:binascii

© www.soinside.com 2019 - 2024. All rights reserved.