2009-11-25 74 views
2

我在解析python中十六進制格式的DEC 32位單精度浮點值時出現問題,我解析的值在十六進制中表示爲D44393DB。從發送單元的顯示中讀取原始浮點值爲〜108。在Python中解析十六進制DEC 32位單精度浮點值

格式規定爲: 1bit符號+8bit指數+23bit尾數。 字節2包含符號位+指數的7個最高有效位 字節1包含指數的最低有效位+尾數的最高有效位。

我發現,在兩種格式不同,唯一的一點是這是在DEC32 128和127在IEEE-754(http://www.irig106.org/docs/106-07/appendixO.pdf

使用http://babbage.cs.qc.edu/IEEE-754/32bit.html不會產生預期的結果,指數的偏差。

/Kristofer

+0

我相信尾數也有不同的表示(IEEE格式有一個隱含的0.5)。我在家裏有一本LSI-11/02手冊 - 如果我今晚找到任何東西,我會發佈一個答案。 – 2009-11-25 16:19:57

+0

無論您是否計數1023或1234,符號位必須位於結束字節中,字節2不能位於結尾。首先傳輸哪個字節,D4還是DB?更好的是,告訴我們每個字節的傳輸順序。你真的只有一個已知的價值? – 2009-11-26 11:24:14

+0

收到的訂單是B1B2B3B4或實際的十六進制:D44393DB 要解析的訂單是B2B1B4B3,在本例中爲:43D4DB93,符號位是B2的MSB。 – Kristofer 2009-11-26 13:38:16

回答

3

難道字節得到了某種程度上洗牌?您描述的位的排列(字節2中的符號位,字節1中指數的LSB)與鏈接到的附錄O不同。它看起來像是交換了字節1和2。

我假定字節3和4也被交換,所以真正的十六進制值是43D4DB93。這將轉換爲二進制的0100 0011 1101 0100 1101 1011 1001 0011,所以符號位爲0,表示正數。指數是10000111(二進制)= 135(十進制),表示因子2 ^(135-128)= 128。最後,尾數是0.1101 0100 1101 1011 1001 0011(二進制),使用附錄O說你有在前面加0.1,即十進制大約爲0.8314。所以我的假設下你的數字是0.8314 * 128 = 106.4。

補充:一些Python 2代碼可能會澄清:

input = 0xD44393DB; 
reshuffled = ((input & 0xFF00FF00) >> 8) | ((input & 0x00FF00FF) << 8); 
signbit = (reshuffled & 0x80000000) >> 31; 
exponent = ((reshuffled & 0x7F800000) >> 23) - 128; 
mantissa = float((reshuffled & 0x007FFFFF) | 0x00800000)/2**24; 
result = (-1)**signbit * mantissa * 2**exponent; 

這就產生result = 106.42885589599609

下面是計算尾數線的解釋。首先,reshuffled & 0x007FFFFF產生編碼尾數的23位:101 0100 1101 1011 1001 0011.然後... | 0x00800000設置隱藏位,產生1101 0100 1101 1011 1001 0011。我們現在必須計算分數0.1101 0100 1101 1011 1001 0011。根據定義,這相當於1*2^(-1) + 1*2^(-2) + 0*2^(-3) + ... + 1*2^(-23) + 1*2^(-24)。這也可以寫成(1*2^23 + 1*2^22 + 0*2^21 + ... + 1*2^1 + 1*2^0)/2^24。括號中的表達式是1101 0100 1101 1011 1001 0011(二進制)的值,所以我們可以通過將(reshuffled & 0x007FFFFF) | 0x00800000除以2^24來找到尾數。

+0

謝謝你的好回答,它指出我的方向是正確的! 您似乎已經切換了原始十六進制值(43D4DB93)的二進制翻譯中的中間字節的順序,應該是: 0100 0011 1101 0100 1101 1011 1001 0011. – Kristofer 2009-11-26 14:15:51

+0

我不確定你是怎麼想出來的二進制到十進制轉換的尾數,所以我嘗試解釋喜歡維基百科:http://en.wikipedia.org/wiki/IEEE_754-1985#A_more_complex_example 哪個遊戲我下面:使用0.1F其中F = 101 0100 1101 (2^-1)+(2^-2)+(2^-4)+(2^-6)的平均值爲1011 1001 0011,其中,n =位位置 )+(2^-9)+(2^-10)+(2^-12)+(2^-13)+(2^-15)... = 0.832466125 .... * 128 =〜106.5556 這就是你計算尾數的方式嗎? – Kristofer 2009-11-26 14:20:21

+0

正如你所說,我在將十六進制值翻譯爲二進制文件時犯了一個錯誤。尾數確實按照你的說法計算。 – 2009-11-26 17:19:07

0

它絕對是一個DEC32值嗎?符號位似乎是1,表示這種格式爲負數。但是,你得到非常接近你108值,如果你忽略了這一點,並假設指數偏差爲15,保留尾數的0.1係數的結果:

def decode(x): 
    exp = (x>>30) & 0xff 
    mantissa = x&((2**24)-1) 
    return 0.1 * mantissa * (2**(exp-15)) 

>>> decode(0xD44393DB) 
108.12409668 
+0

偏差不大可能是15. – 2009-11-26 11:27:45

1

從我的「微型計算機和回憶」(DEC,1981)的副本中,你對兩種格式之間的區別是正確的。 DEC尾數歸一化爲0.5<=f<1,IEEE格式尾數歸一化爲1<=f<2,這兩個都是MSB隱式和未存儲的。因此尾數位佈局是相同的。由於D44393DB的值爲-0.7639748 X 2^40(即-8.3999923E11),Jitse Niesens的假設看起來像一個合理的解釋。

+0

0.1F給出DEC的起始值0.5,而IEEE 1.F給出起始值1 – Kristofer 2009-11-26 14:15:16