繁体   English   中英

Python输出奇怪的bytearray

[英]Python outputs strange bytearray

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

>>> 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字节,首先? 为什么需要这种额外的魔力?


>>> 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'

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

>>> 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但在程序中使用floatf的说明符。 这就是你得到的:

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 ()

结果:

The bytes:
1f85eb51b81e0940
9a99999999990540
0000000000000000
000000000000f0bf
9a9999999999f13f

Python在打印时输出“奇怪”行为,因为print功能会尝试将任何ASCII可打印字符打印为ASCII, 而不是十六进制。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM