簡體   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