1

我正在生成用於模擬網絡的單元測試中的二進制文件。通過網絡發送的一些數據採用小端模式或大端模式,我想用存根模擬這些數據並創建二進制文件。因此,換句話說,我將生成二進制文件,其中包含我期望從網絡套接字獲得的等效數據的二進制文件,而不是使用活動網絡進行單元測試。將float數組轉換成little/big endian

我正在使用Python 2.7來生成字節數組並將它們保存到文件中,但我無法將我的float數組轉換爲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()它會在小/大端模式寫入二進制數據。

該代碼給出了以下的輸出:

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'。有沒有可能這些文件編寫得很好,但是用來讀取它們並顯示它們和/或重新排列的代碼 - 如果它們(您沒有向我們顯示)是錯誤的? – abarnert 2013-05-08 21:58:14

回答

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的計數,你顯然會將前四個雙打看作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字節浮點數 – 2013-05-08 22:03:32

+0

哦,我看到'array('d',..)'應該是'f'。現在讓我試試看! – 2013-05-08 22:05:54

+0

@EricS:好的,同樣的問題,但我向後描述了它。讓我編輯答案。 – abarnert 2013-05-08 22:07:52