轉載 IEEE 標準的 float 及 double 格式
Posted By: BlackCat (Paul) on board 'ee'
Date: Sat Apr 16 19:02:43 1994
Title: 轉載 IEEE 標準的 float 及 double 格式
Posted By: Alexander (小餅)
Date : Sat Apr 16 17:13:00 1994
Title : IEEE 標準的 float 及 double 格式.
鑑於有人問到在 C 語言中 float 和 double 型態的儲存格式的問題, 所以我就在
這邊獻醜一翻, 講講我所瞭解的部份, 如有任何錯誤, 請各位電機人多多指教...
IEEE 制定之浮點數格式說明:
float 型態: 用 4 個 bytes 儲存, 也就是 32 bits.
各個 bit 的用途如下:
bit 31 23~30 0~22
┌───┬────┬───────┐
│正負號│ 指數 │ 底數 │
└───┴────┴───────┘
double 型態: 用 8 個 bytes 儲存, 也就是 64 bits.
各個 bit 的用途如下:
bit 63 52~62 0~51
┌───┬────┬───────┐
│正負號│ 指數 │ 底數 │
└───┴────┴───────┘
< 說明 > 正負號 (sign): 1 為負, 0 為正.
指數 (exponential): 將底數乘上 2 的指數次方後就是原來的數.
須注意的是: float 時, 因有 8 bits, 所以能表示的有 2 的
256 次方, 但因為指數應可正可負, 所以 IEEE 規定, 此處算
出的次方須減去 127 纔是真的指數,所以 float 的指數可從
-126 到 128.
同理, double 型態有 11 bits, 算出的值須減去 1023, 所以
double 的指數可從 -1022 到 1024.
底數 (mantissa): 此部份格式實在難以用文字說明,
請參考下面的例子.
< 特例 > 0 因為無法用任何 2 的次方表示, 所以 0 的表示法就是
float : 00 00 00 00
double: 00 00 00 00 00 00 00 00
< 範例 > 將 17.625 換算成 float 型態.
首先, 先將 17.625 換算成 2 進位: 10001.101
(甚麼 ?? 你問我小數是怎麼換的 ?? 好吧,就告訴你好了, 因為
0.625 = 0.5 + 0.125 , 0.5 即 1/2 , 0.125 即 1/8 , 所以
0.625 換算成 2 進位是 0.101 , 如果你還沒懂, 請你再問別
人. 當然, 這裡的數字是為了講解方便才用這麼完美的小數,
實際的小數部份, 是用無限逼近出來的.)
再來將 10001.101 向右 shift 直到小數點前只剩一位 (這一位
數當然是 1), 變成了 1.0001101 x 2 的 4 次方 (因為向右移了
4 位). 此時, 我們要的底數和指數就出來了: 底數部份,因為小
數點前必為 1, 所以 IEEE 規定只記錄小數點後的就好, 所以此
題的底數為 0001101 . 指數部份實際為 4, 但在格式中須加上
127 , 固為 131 , 即二進位的 10000011.
綜合上列各項, 17.625 的 float 儲存格式就是:
0 10000011 00011010000000000000000
轉換成 byte : 41 8D 00 00
另外, 因為 INTEL CPU 是 little endian 的, 所以
41 8D 00 00 在記憶體中是按 00 00 8D 41 的順序放的. (位址
由低到高)
以上的資料, 都可以在 Borland C++ 的 IDE 環境下, 用 watch 的功能觀察證
明出來.
參考資料: Computer Organization (3rd ed.) p.304 ~ p.306
McGRAW-HILL Int'l
Authors: V. Carl Hamacher
Zvonko G. Vranesic
Safwat G. Zaky
終於打完了, 希望大家看得懂, 有問題也歡迎問. 這一篇也許可以建議 Board
Manager 複製到 EE board 的精華區內, 讓我能名留青史 :-)
也希望老師們萬一看到了, 唸在苦勞的份上, 將我的成績多加幾分, 我的學號
是 8031xxx (啊!! 為了生命安危起見,我還是隱名埋姓好了 ....)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.