IEEE 754 轉換工具|浮點數⇔位模式互轉(32/64位)
十進位制小數與IEEE 754位模式(單精度32位・雙精度64位)雙向互轉。符號位、指數部、尾數部分色顯示,NaN、無窮大與非規格化數一目了然。
經典案例:為什麼 0.1 + 0.2 不等於 0.3
在JavaScript中計算 `0.1 + 0.2` 得到的是 `0.30000000000000004`,而非 `0.3`。檢視雙精度的位模式即可理解原因。
| 數值 | 雙精度(64位)十六進位制 | 雙精度(64位)二進位制 |
|---|---|---|
| 0.1 | 0x3FB999999999999A | 0011111110111001100110011001100110011001100110011001100110011010 |
| 0.2 | 0x3FC999999999999A | 0011111111001001100110011001100110011001100110011001100110011010 |
| 0.3 | 0x3FD3333333333333 | 0011111111010011001100110011001100110011001100110011001100110011 |
| 0.1 + 0.2 | 0x3FD3333333333334 | 0011111111010011001100110011001100110011001100110011001100110100 |
0.1、0.2、0.3在二進位制中都是無限迴圈小數,無法完全放入52位的尾數部分,因此都會被四捨五入。由於0.1與0.2各自的舍入誤差方向恰好沒有抵消,兩者相加的結果與0.3的精確位模式相比只相差最後1位(0x3FD3333333333334)。可以在上方的轉換工具中親自輸入這些數值,比較末位的差異。
什麼是IEEE 754?用位模式看浮點數
電腦在儲存一個十進位制小數時,並不會原樣保留你輸入的數字,而是按照IEEE 754標準,把這個值拆分成符號、指數部、尾數部三部分,裝進固定長度的位元(bit)中。這個工具可以讓你直接看到,任意輸入值在單精度(32位)和雙精度(64位)下分別被存成了怎樣的位模式,也支援反向操作:貼上一段十六進位制或二進位制位模式,就能知道它對應的十進位制數值。
日常程式設計中很少需要關心這一層,但`0.1 + 0.2`為什麼不等於`0.3`、超大整數存成浮點數後為什麼會遺失精度、NaN與無窮大在比較運算中為何表現特殊,答案都藏在這套位結構裡。把符號位、指數部、尾數部拆開擺在一個真實數值上,抽象的規則就變得可以直接指認了。
使用方法
- 選擇轉換方向與精度 選擇「十進位制 → 位模式」或「位模式 → 十進位制」,再指定單精度(32位)或雙精度(64位)。
- 輸入數值 十進位制輸入除一般數字外,還可輸入「NaN」・「Infinity」・「-Infinity」。位模式輸入需使用`0x`開頭的十六進位制,或位數與所選精度一致的二進位制。
- 查看符號・指數部・尾數部的拆解 透過分色顯示的位元串與詳情表,確認原始指數值、去除偏移後的實際指數值以及完整的十六進位制表示。
- 閱讀分類標籤與說明 結果會被自動判定為零・非規格化數・規格化數・無窮大・NaN之一,並附有簡要說明。
- 嘗試預設按鈕與邊界情形 點選0.1・0.2・0.3、±0、±Infinity、NaN的預設按鈕,或輸入負數及極大/極小的數值,比較它們的編碼結果。
用好本工具的小技巧
- 將0.1、0.2、0.3分別以雙精度轉換為位模式,並與0.1+0.2的結果(0.30000000000000004)對比,可以直觀地發現只有最後1位不同。
- 在十進位制輸入框中輸入"-0",會得到只有符號位為1的位模式(與"+0"不同)。作為數值0===-0成立,但位表示本身是不同的。
- 當指數部全為0時,尾數部為0表示零,尾數部不為0則表示非規格化數——一種以犧牲精度為代價來表示極接近零的數值的特殊表示法。
- 將同一數值(如0.1)在單精度(32位)與雙精度(64位)之間切換,可以確認單精度的舍入誤差更大。
- 將位模式解碼為十進位制時,需要輸入以`0x`開頭的十六進位制字串,或位數與所選精度完全一致的二進位制字串(`0b`字首可省略)。
適用場景
電腦科學課程學習
教科書上抽象描述的浮點數內部結構,可以用真實數值直接驗證,適合複習或撰寫實驗報告時使用。
排查數值精度相關的程式錯誤
不用寫程式碼,只需輸入可疑數值查看其精確位模式,就能縮小「為什麼偏偏這個計算出現誤差」的原因範圍。
嵌入式與底層程式設計
把記憶體傾印或暫存器中看到的十六進位制浮點數值,反向解碼成易讀的十進位制數值。
技術面試與筆試準備
針對「單精度與雙精度在位元級別上有何區別」這類常見問題,用具體例子而非死記硬背來準備答案。
向他人解釋「0.1 + 0.2 ≠ 0.3」
不必只靠口頭斷言捨入誤差,直接展示實際的位模式對比,讓對方一眼看懂。
術語表
- IEEE 754
- 規定電腦如何表示浮點數的國際標準。1985年發布,幾乎所有程式語言的float/double型別都遵循這一規格。
- 符號位
- 表示數值正負的1個位元。0為正、1為負,獨立於指數部與尾數部之外,因此「+0」與「-0」作為不同的位模式而存在。
- 指數部
- 表示數值量級(大小規模)的位元串,單精度為8位、雙精度為11位,以加上偏移量後的形式儲存。
- 尾數部
- 表示數值有效數字(精度)的位元串,單精度為23位、雙精度為52位,通常按開頭帶有隱含1的方式解讀。
- 偏移量(bias)
- 為了讓指數部能以無符號整數形式儲存和比較而加上的固定值,單精度為127、雙精度為1023。
- 非規格化數
- 指數部全為0且尾數部不為0的位模式。省略尾數部開頭的隱含1,以犧牲精度為代價表示比通常最小值更接近零的數值。
- NaN(非數)
- 指數部全為1且尾數部不為0的位模式,由0/0、∞-∞等數學上未定義的運算產生。
- 無窮大
- 指數部全為1且尾數部全為0的位模式,通常在計算結果超出可表示範圍(溢位)時出現。
常見問題
閒話 ― IEEE 754如何成為一門"通用語言"
1985年以前,各計算機制造商都採用各自獨立的浮點數表示法。IBM、DEC、Cray等公司即便計算同一個"0.1",其舍入方式與可表示的數值範圍也會存在細微差異,導致在一臺機器上編寫的數值計算程式移植到另一臺機器時,結果往往會出現微小偏差。為了解決這一混亂局面,曾參與英特爾8087數值協處理器設計的加州大學伯克利分校學者William Kahan牽頭組織了跨行業的標準化工作,於1985年釋出了IEEE 754標準。
IEEE 754的核心思想,是將有限的位數(32位或64位)劃分為符號、指數部、尾數部三個部分的分工,以此近似表示無限多的實數。指數部負責數值的量級(大小規模),尾數部負責有效數字的精度,這樣即使位數有限,也能靈活覆蓋從極小到極大的數值範圍。指數部之所以要加上偏移量(單精度為127、雙精度為1023)後再儲存,是為了避免像有符號整數的補碼那樣複雜的符號處理,只需將位串作為普通整數直接比較即可判斷數值大小關係。
在二進位制中能夠被"精確"表示的小數,僅限於分母為2的冪的分數(如1/2、1/4、3/8等)。十進位制的0.1寫成分數是1/10,由於10不是2的冪,在二進位制中會變成0.0001100110011...這樣無限迴圈的小數。由於尾數部的位數有限,只能在某處截斷並四捨五入,這正是"計算機無法精確表示0.1"的根本原因。需要精確處理十進位制小數的會計系統之所以往往不使用浮點數,而改用整數運算或專門的十進位制型別(如BCD),原因也在於此。
IEEE 754此後在2008年、2019年經歷了修訂,新增了半精度(16位)、四倍精度(128位)以及十進位制浮點數等規定,但符號、指數部、尾數部三分結構以及舍入模式的核心思想,自1985年初版以來從未改變。由於幾乎所有程式語言的float/double型別都遵循這一標準,"為什麼0.1+0.2不等於0.3"這一疑問,無論在哪種程式語言中都會以相同的形式出現。