Python иногда генерирует странные загадочные байтовые массивы. Я не знаю, как их интерпретировать.Python выводит странный bytearray
Рассмотрим следующий пример.
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 должна выводить «байты-представления» каждого значения в списке. Список состоит из чисел с плавающей точкой 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\[email protected]\xcd\xcc,@\x00\x00\x00\x00\x00\x00\x80\xbf\xcd\xcc\x8c?'
Пожалуйста, помогите мне понять, что здесь делает Python.
EDIT
Видимо я должен использовать 'd'
вместо 'f'
, поскольку я использую двойной точности с плавающей запятой на моей машине. Благодарю вас. Rad Lexus для вашего ответа. Но я все еще немного озадачен выводами 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\[email protected]',
b'\x9a\x99\x99\x99\x99\x99\[email protected]',
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-байтовое представление соответствующего числа с плавающей точкой - за исключением float 0.0
.
Ваш код продолжает с некоторой магии, чтобы извлечь фактические правильные 8 байт за поплавком:
print("The bytes:")
for floatInHex in s:
for byteval in floatInHex:
print ('%02x' % byteval, end="")
Теперь мы получаем правильный результат. Но почему объект s
еще не содержит правильные 8 байтов на каждый поплавок? Зачем нужна эта дополнительная магия?
Я все еще немного озадачен тем, что выводит Python. Пожалуйста, проверьте ** EDIT ** по моему вопросу. Огромное спасибо. –
@ K.Mulier, Python repesent character i строка как символ (вместо экранированного шестнадцатеричного формата), если он представлен таким образом. 'b '@' == b '\ x40'' – falsetru
Большое вам спасибо. В этом случае вещи начинают меня понимать. Тем не менее, я заметил, что последовательность байтов изменяется по порядку. Это верно? –