2011-08-08 67 views
1

我測試IEEE 754使用下面的例子浮動格式VS2008:IEEE 754浮點數調試 - 從內存小端實際浮點數

int main(int argc, char *argv[]) 
{ 
    float i = 0.15625; 
} 

我把&我到VS2008手錶,我看到了地址是0x0012FF60,我可以看到地址的內容是00 00 20 3E從內存調試窗口,見下圖:

0x0012FF60 00 00 20 3E CC CC CC CC

順便說一句我有IEEE754浮點格式的基本知識,我知道IEEE 754浮點格式由三個字段組成:符號位,指數和分數。分數是沒有最重要位的有效數。

但是我是怎麼從小尾數00 00 20 3e到0.15625精確計算的?

非常感謝

+0

感謝所有的投入,現在真的很清楚,爲每個人打勾! – Gob00st

回答

3

要打印出來的東西破碎。我們只需要32位,它們是:

00 00 20 3E 

你在二元變量:

00000000 00000000 00100000 00111110 

邏輯值佔小尾數:

00111110 00100000 00000000 00000000 

根據IEEE:

0 01111100 01000000000000000000000 
S E - 127 M - 1 

所以現在它清理R:

  • 的符號1(S = 0
  • 指數爲124 - 127 = -3
  • 的mantissaa是1.01b,這是5/4

所以值是5/4/8 = 5/32 = 0.15625。

+0

我只發佈cc cc cc cc去展示這是內存邊界... – Gob00st

+0

這不是一個打印,這是我從VS2008內存調試窗口複製 – Gob00st

6

32位浮點數的內存佈局(見http://en.wikipedia.org/wiki/Single_precision)大端機器上。

enter image description here

小endian機器(例如,86)簡單地交換對字節,「抄送」是存儲器未使用的比特以使32位浮子高達64位值由調試器正在顯示

編輯: 記住指數是有符號的(二進制補碼),因爲0.15625小於1,指數是負數)

value = sign * 2^exp *尾數。

0x3E的= 0011 1110
爲0x20 = 0010 0000

因爲符號位,我們必須沿着一個這樣
指數= 0111 1100 = -3
尾數= 0100 0000 = 1 + 0.25洗牌這些的(假設在第一位置之前的那個)

即0.15625 = 1 * 2 ^( - 3)×1.25

+0

這張圖片中的位順序是什麼?它被讀爲7C 40,即使是相反的順序(假設它是大端的?),它是02 3e,而不是20 3e。我在這裏錯過了很明顯的東西嗎 – Gob00st

+0

我很懷疑「交換字節對」,這不是OP機器上發生的事情。 –

+1

另外,指數不是「簽名」,它是「偏見」! –

1

你的價值是十六進制0x3E200000或

0011 1110 0010 0000 0000 0000 0000 0000 

或重排:

s ----e--- ----------m------------ 
0 01111100 01000000000000000000000 

sign_bit = 0 (i.e. positive) 
exponent = 0x7C = 124 ---> subtract 127 to get -3 
significand = 1 + 0.0100... = 1.0100... = 1*2^0 + 0*2^-1 + 1*2^-2 = 1.25 

significand * 2^exponent = 1.25 * 2^-3 = 1.25 * 0.125 = 0.15625 
+0

爲什麼' -4'?爲什麼符號是「零」? –

+0

符號***位***爲零。 -4是一個錯字,並予以糾正。將符號重命名爲sign_bit。 –

1

一個IEEE浮點的基本格式是基於四個字節0​​價值,這是簡單的分析如果你這樣顯示它。在那 的情況下,最高位是指數,接下來的8位指數(超過 127),其餘爲尾數。解釋它的最簡單方法是 可能展現C++代碼,就可以訪問不同的領域:

double d; 
// ... 
uint32_t const* p = reinterpret_cast<uint32_t const*>(&d); 
bool isNegative = (*p & 0x80000000) != 0; 
int exp = ((*p & 0x78000000) >> 23) - 127; 
int mantissa = (*p & 0x07FFFFFF) | 0x08000000 ; 

尾數應該有一個隱含的小數位略高於24 位(但我不知道該怎麼把它表示爲一個整數:-))。

如果您擁有的只是一個字節序列,則必須根據字節順序將它們組合起來,然後應用上述內容。

編輯:常數值已被糾正,隨後Rudy Velthuis'指出我的錯誤。

+0

即'int exp =((* p&0x78000000)>> 23) - 127;'和isNegative一樣。 –

+0

@Rudy是的。我不知道我在想什麼。在遙遠的過去,我在16位機器上做了很多工作,但我從來沒有見過16位浮點格式:-)我將對它進行編輯(所有十六進制值都會受到影響)---感謝修正。 –