天天看點

浮點數在計算機中的編碼方式

在閱讀《C++反彙編與逆向分析技術揭秘》一書中遇到了一個有趣的問題,摘出來跟大家分享下。

浮點數在計算機中的編碼方式

浮點數編碼轉換采用的是IEEE規定的編碼标準,float和double這兩種類型資料的轉換原理相同,隻是用于表示的範圍有些差別,IEEE規定的浮點數編碼會将一個浮點數轉換為二進制數。**以科學記數法劃分,将浮點數拆為3部分:符号、指數、尾數。

float類型在記憶體中占4位元組(32位)。其中最高位用于表示符号**;再剩下的31位中,從右往左取8位用于表示指數,其餘的表示尾數,如上圖所示

以12.25f為例:

12.25對應的二進制:1100.01,整數部分為1100,小數部分為01。(整數了解不難,小數為什麼這樣呢?)

小數部分轉化二進制采用的是不同方法:十進制小數轉換成二進制小數采用"乘2取整

不了解的同學點這裡:小數轉化二進制的方法

具體做法是:用2乘十進制小數,可以得到積,将積的整數部分取出,再用2乘餘下的小數部分,又得到一個積,再将積的整數部分取出,如此進行,直到積中的小數部分為零,此時0或1為二進制的最後一位。或者達到所要求的精度為止。
比如小數為0.25:
0.25*2 = 0.5  取0
0.5*2  = 1.0  取1
是以結果就是01了
           

結果12.25轉化二進制結果是1100.01,接下來用科學記數法表示的話,小數點移動三位,則指數位為3并且需要加上127,這是為什麼呢?書中提到:

由于指數可能出現負數,十進制數127可表示為二進制數01111111.IEEE編碼方式規定,當指數域小于01111111時為一個負數,反之為正數,是以01111111為0(這裡了解記憶就行了感覺)

以上就解決了符号位,指數位了。符号位為 0,指數位為(3+127)二進制表示為10000010

接下來尾數位則作下拼接:12.25二進制剩下的低位用0補全到23位的尾數位,并且在IEEE編碼中尾數位最高位恒為1,故此忽略不計

結果---------0 10000010 10001000000000000000000,對應的Hex = 0x41440000

例題2:-0.125f

同樣的步驟:

小數位轉化二進制:

0.1252 = 0.25 :0

0.252 = 0.5 :0

0.5 * 2 = 1 :1

轉化結果 0.001,科學記數法表示為1x10^-3

符号位:1(負數)

指數位:-3+127(原因上文提到了)二進制表示為0111 1100

尾數 :00000000000000000000000

結果:1 0111 1100 00000000000000000000000,對應的Hex = 0xBE000000

例題3:(比較特殊一點)1.3f

轉化二進制:1.010011001100110011001…(循環1001因為乘2取整是無窮的,不信你們試試,哈哈)

符号位:1

指數位:0+127 二進制:01111111

尾數 :01001100110011001…考慮到float的精度範圍,舍棄了精度範圍之外的小數位

結果 :10111111101001100110011001100110, 對應的hex = 0x3FA66666