1

Я генерирую двоичные файлы для использования в модульных тестах, которые имитируют сеть. Некоторые из данных, отправленных по сети, находятся в режиме Little Endian или Big Endian, и я хотел бы имитировать эти данные с помощью заглушки и создания двоичных файлов.Преобразование массива float в little/big endian

Другими словами, вместо использования активной сети для моих модульных тестов я бы сгенерировал двоичные файлы, содержащие эквивалентные данные, которые я ожидал бы от сетевых сокетов.

Я использую Python 2.7 для генерации массивов байтов и сохранения их в файлах, но у меня возникли проблемы с преобразованием моего массива с плавающей точкой в ​​режим little endian.

from array import array 
output_file = open(r"C:\temp\bin.dat", "wb") 
float_array = array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72]) 
float_array.byteswap(); #This doesn't convert it to little endian! 
float_array.tofile(output_file) 
output_file.close() 

Так что я интересно, если кто-нибудь знает, как от, как манипулировать массив таким образом, что, когда я float_array.tofile() он будет записывать двоичные данные в маленьком/режиме большой Endian.

Этот код дает следующий результат:

Val = 8.6184E-41 
Val = 0.0 
Val = 4.1897916E-8 
Val = 4.172325E-8 
Val = -1.9212016E-29 
Val = -490.3153 
Val = -1.5834067E-23 

Который не соответствует разыскиваемых array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72])

Когда я закомментировать метод byteswap, я получаю следующее

Val = 0.0 
Val = 1.875 
Val = 4.172325E-8 
Val = 1.9 
Val = 1.9023206E17 
Val = 1.67 
Val = -1.5881868E-23 

Однако , в реальном сетевом режиме он отлично работает. Но это не помогает при модульном тестировании!

+0

Я смущен. Где вы получаете эти строки «Val = 0.0»? Когда я запускаю свой код, я получаю двоичные файлы, а не что-то в этом формате. И первые 8 байтов являются «0, 0, 0, 0, 0, 0, 240, 63', если они не заменены,' 63, 240, 0, 0, 0, 0, 0, 0', если они меняются местами. Возможно ли, что файлы написаны очень хорошо, но код, который вы используете для их чтения и отображения и/или повторного массива-ify (который вы нам не показали), неверен? – abarnert

ответ

3

Код, который вы нам показали, представляет собой массив из 8 (64-разрядных) удвоений. Код, который вы нам не показывали, это чтение массива из 4 (32-битных) поплавков. Помимо этой проблемы, они оба правильны.

Решение должно использовать 'f' здесь, или 'd' там, поэтому ваше чтение и письмо совпадают.

Для проверки:

>>> float_array = array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72]) 
>>> float_array.byteswap() 
>>> s = float_array.tostring() 
>>> new_float_array = array('f') 
>>> new_float_array.fromstring(s) 
>>> new_float_array 
array('f', [8.618405945136922e-41, 0.0, 4.189791624753525e-08, 4.17232506322307e-08, -1.9212016359104883e-29, -490.3153076171875, -1.5834066576694083e-23, -6.352746725754018e-23, -360092172025856.0, -5.209340637631123e-17, -1.5917267736367743e-23, -6.352746725754018e-23, -2.141351348326541e+32, 4.89745031096063e-14, 2.950574046482335e-41, 0.0]) 

Посмотрите знакомые? Теперь достаньте byteswap:

>>> float_array = array('d', [1, 1.2, 0.34, 9.8, 0.13, 1.1, 0.88, 72]) 
>>> s = float_array.tostring() 
>>> new_float_array = array('f') 
>>> new_float_array.fromstring(s) 
>>> new_float_array 
array('f', [0.0, 1.875, 4.17232506322307e-08, 1.899999976158142, 1.902320558192722e+17, 1.6699999570846558, -1.5881868392106856e-23, 2.5562498569488525, 9.121204334167384e-33, 1.5049999952316284, -1.5881868392106856e-23, 1.8874999284744263, -71.68000030517578, 1.84499990940094, 0.0, 3.28125]) 

Обратите внимание, что я использую tostring/fromstring для удобства, вместо tofile/fromfile, что означает, что я не указать количество. Но если вы укажете счет 8, вы, очевидно, будете читать первые 4 удвоения в виде 8 поплавков. И если вы затем отформатируете их так, чтобы они выглядели как ваш выход:

>>> print '\n'.join('Val = {}'.format(val) for val in new_float_array[8]) 
Val = 8.6184E-41 
Val = 0.0 
Val = 4.1897916E-8 
Val = 4.172325E-8 
Val = -1.9212016E-29 
Val = -490.3153 
Val = -1.5834067E-23 
+0

Нет двухместных чисел, все 4 байтовых поплавков –

+0

Охх, я вижу, 'array ('d', ..)' должен быть 'f'. Позвольте мне попробовать это сейчас! –

+0

@ Эрик: Хорошо, та же проблема, но я описал ее назад. Позвольте мне отредактировать ответ. – abarnert

Смежные вопросы