浮點數(IEEE 754)轉換工具
輸入十進位數,即可以顏色區分顯示它在 IEEE 754 半精度(16 位元)、單精度(32 位元)、雙精度(64 位元)下的符號、指數部分、尾數位元串與十六進位表示。工具會以精確的十進位數顯示實際儲存的值,並計算與輸入的誤差,讓你確認 0.1 為何無法精確表示,以及各格式在精度與範圍上的差異。也可以修改十六進位位元串,反推回數值。
結果
符號 指數部分 尾數
- 十六進位
- –
- 類別
- –
- 符號
- –
- 指數部分
- –
- 尾數
- –
- 實際儲存的值
- –
- 誤差(儲存值 − 輸入)
- –
此格式的特性
- 精度
- –
- 機器 epsilon
- –
- 最大值
- –
- 最小正規化數
- –
- 最小非正規化數
- –
捨入方式為捨入至最接近偶數。修改十六進位欄位後,會讀取該位元串所代表的值。
以圖表檢視
其他輸入維持目前的值,只讓選擇的輸入在目前值的 1/4 到 4 倍之間變化時的結果。紅點是目前的值。
符號、指數部分、尾數的結構與偏移值
IEEE 754 浮點數以 (−1)^符號 × 1.尾數 × 2^(指數部分 − 偏移值) 的形式記錄數值。位元數分配為:半精度是符號 1、指數部分 5、尾數 10,單精度是 1、8、23,雙精度是 1、11、52;偏移值分別為 15、127、1023。記錄實際指數加上偏移值後的值,是為了讓負的指數也能當作無號整數處理。正規化數的尾數開頭一定是 1,因此不記錄這個 1(隱藏位元),單精度便能以 23 位元的記錄得到 24 位元的精度。工具會以顏色區分符號、指數部分與尾數,並以「記錄值 − 偏移值 = 實際指數」的形式顯示指數部分。
範例:以單精度表示 0.1
0.1 在二進位中是 0.000110011001100…,即 0011 無限重複的小數,正規化後為 1.10011001100…(2) × 2⁻⁴。在單精度中,指數部分為 −4 + 127 = 123(0111 1011)。尾數在小數點後 23 位元處截斷時,剩餘部分大於一半,因此進位為 10011001100110011001101。排列起來是 0 01111011 10011001100110011001101,十六進位為 0x3DCCCCCD。這個位元串實際代表的值是 0.100000001490116119384765625,誤差約為 1.49 × 10⁻⁹。分母不是 2 的冪次的分數無法以有限位數的二進位表示,所以 0.1 不論用多少位元都無法精確表示。改用雙精度時為 0x3FB999999999999A,誤差縮小到約 5.55 × 10⁻¹⁸,但仍不會是 0。
非正規化數、零、無限大與 NaN
指數部分全為 0 與全為 1 的位元串保留給特殊值使用。指數部分全為 0 且尾數為 0 時是零(依符號位元分為 +0 與 −0),尾數不為 0 時則是非正規化數。非正規化數不假設開頭的 1,表示 0.尾數 × 2^(1 − 偏移值),以等間隔的值填補 0 與最小正規化數(單精度為 2⁻¹²⁶ ≈ 1.175 × 10⁻³⁸)之間的空隙。這稱為漸進式下溢,單精度的最小非正規化數為 2⁻¹⁴⁹ ≈ 1.401 × 10⁻⁴⁵。不過值越小,可用的尾數位數越少,精度也隨之下降。指數部分全為 1 時,尾數為 0 代表無限大,不為 0 則代表 NaN(非數)。在單精度下輸入 1e-40 會得到非正規化數,輸入 1e39 則會得到無限大,可在工具中確認。
捨入、機器 epsilon 與計算誤差
無法表示的值會捨入到最接近的可表示值,恰好在中間時,則選擇尾數最低位元為 0(偶數)的一方(捨入至最接近偶數)。1 與比 1 大的下一個可表示數之差稱為機器 epsilon,半精度為 2⁻¹⁰ ≈ 9.766 × 10⁻⁴,單精度為 2⁻²³ ≈ 1.192 × 10⁻⁷,雙精度為 2⁻⁵² ≈ 2.220 × 10⁻¹⁶。在正規化數的範圍內,捨入造成的相對誤差不超過其一半。誤差真正造成問題,是在計算過程中被放大的時候:幾乎相等的兩數相減時,高位數互相抵消,有效位數大幅減少(有效位數損失);大小相差懸殊的兩數相加時,較小數的低位數會遺失(資訊遺失)。在單精度下輸入 1.0000001,會儲存為 1.00000011920928955078125,因此減去 1 後約為 1.19 × 10⁻⁷,比原本的 1 × 10⁻⁷ 大了將近兩成。輸入 100000001 則會變成 100000000,可看出 1 億加 1 後數值不變。另外,本工具轉換為單精度與半精度時,會先把輸入轉為雙精度值再捨入,因此對於極接近中間點的輸入,結果的最低位元可能與直接捨入不同。
半精度、bfloat16 與 AI 的應用
半精度(FP16)為 16 位元,與單精度相比可將記憶體用量與傳輸量減半,但指數部分只有 5 位元,最大值為 65504,最小正規化數為 2⁻¹⁴ ≈ 6.104 × 10⁻⁵,範圍較窄。在工具中,65519 會捨入為 65504,65520 以上則成為無限大。以 FP16 訓練 AI 模型時,會使用損失縮放(loss scaling)防止微小的梯度變成 0。bfloat16 是符號 1、指數部分 8、尾數 7 位元的 16 位元格式,指數部分與單精度相同,因此範圍與單精度幾乎相同,但精度只有 8 位元(約 2.4 位十進位數)。它的排列與單精度的高 16 位元相同,轉換容易,常用於 AI 訓練。本工具不支援 bfloat16 與 FP8。若要求 bfloat16 的值,可取單精度十六進位的高 4 位數,並以捨入至最接近偶數的方式處理低 16 位元。例如 0.1 的單精度為 0x3DCCCCCD,低位的 CCCD 大於中間點 8000,因此進位,bfloat16 為 0x3DCD(0.10009765625)。
練習電腦算術題目
- A0xC0C80000
- B0x40C80000
- C0xC0A80000
查看答案與解析
正確答案:A. 0xC0C80000
將6.25轉為二進位為110.01,正規化後為 1.1001 × 2²。符號為負,因此是1;指數部分為 2 + 127 = 129 = 1000 0001;尾數則是小數部分的1001後面接續0。排列起來是 1 10000001 1001000…0,每4位元分組後為 1100 0000 1100 1000 0000 …,即 0xC0C80000。0x40C80000的符號位元為0,表示+6.25;0xC0A80000的尾數為0101,表示 −5.25。
- A以二進位也能剛好表示為0.1,因此不會產生誤差
- B在二進位中會成為無限循環小數,因此只能以捨入後的近似值來表示
- C以二進位表示時,會變成比原值剛好大10倍的值
查看答案與解析
正確答案:B. 在二進位中會成為無限循環小數,因此只能以捨入後的近似值來表示
十進位的0.1轉為二進位後,會成為0.000110011001100…,即0011無限重複的小數。浮點數的尾數位數有限,只能記錄中途捨入後的近似值,因此會產生些微的誤差。分母不是2的冪次的分數,都無法以有限的位數用二進位表示。另一方面,像0.5、0.25這類分母為2的冪次的數則能精確表示。不會發生使值變成10倍的轉換。
- A32768
- B65536
- C65504
查看答案與解析
正確答案:C. 65504
指數部分全為1(31)是用於無限大與NaN,因此最大的指數部分為30,實際指數為 30 − 15 = 15。當尾數全為1時,值為 (1 + 1 − 2⁻¹⁰) × 2¹⁵ = (2 − 2⁻¹⁰) × 32768 = 65536 − 32 = 65504。超過此值的結果會成為無限大,因此在以FP16訓練時也須留意溢位。32768是尾數為0時的 2¹⁵,65536是 2¹⁶,兩者都不是最大值。
常見問題
0.1 以單精度表示,十六進位是多少?
是 0x3DCCCCCD。符號為 0,指數部分為 123(實際指數為 −4),尾數為 1.10011001100110011001101(2),實際儲存的值為 0.100000001490116119384765625。以雙精度表示為 0x3FB999999999999A,以半精度表示則為 0x2E66。
為什麼 0.1 + 0.2 不等於 0.3?
因為 0.1、0.2、0.3 都無法以二進位精確表示,各自會被捨入為相近的值。在雙精度下,0.1 與 0.2 會儲存為稍大的值,0.3 則儲存為稍小的值,可從工具中誤差的正負確認。0.1 + 0.2 的結果為 0.3000000000000000444…,位元串為 0x3FD3333333333334,與 0.3 的位元串 0x3FD3333333333333 在最低位元相差 1。比較浮點數時,應以兩者差的絕對值是否夠小來判斷。
單精度與雙精度的機器 epsilon 是多少?
若定義為 1 與比 1 大的下一個可表示數之差,單精度為 2⁻²³ ≈ 1.192 × 10⁻⁷,雙精度為 2⁻⁵² ≈ 2.220 × 10⁻¹⁶,半精度為 2⁻¹⁰ ≈ 9.766 × 10⁻⁴。有些文獻把它的一半(捨入相對誤差的上限)也稱為機器 epsilon,請確認所採用的定義。
單精度可以精確表示到多大的整數?
單精度的精度為 24 位元,因此到 2²⁴ = 16777216 為止的所有整數都能精確表示。輸入 16777217 時,它恰好位於 16777216 與 16777218 的中間,依捨入至最接近偶數會成為 16777216,誤差為 −1。雙精度可精確表示到 2⁵³ = 9007199254740992,半精度則到 2¹¹ = 2048。
如何由十六進位位元串求出數值?
在「位元串(十六進位)」欄位輸入不超過所選格式位數的十六進位數(半精度 4 位、單精度 8 位、雙精度 16 位),工具就會將它分為符號、指數部分與尾數並讀出數值。例如在單精度下,3F800000 為 1,C0C80000 為 −6.25,7F800000 為 +∞,7FC00000 為 NaN。開頭加上 0x 也可以。