浮點數運算與數值表示

正規化浮點數

科學記號有個有禮貌的約定:你寫 6.022 * 10^23,而不寫 0.6022 * 10^24 或 60.22 * 10^22。小數點前恰好有一個非零數字,所以表示法唯一。浮點數採用同樣的規則。正規化數(normalized number)就是其尾數的領先數字位於標準位置者——在二進位中這意味著 1.fffff * 2^e 的形式,二進位小數點前剛好有一個 1。

由於在 2 為基底時,正規化數的那個領先數字「永遠」是 1,IEEE 標準索性不去儲存它。這就是「隱含領先位元」或「隱藏位元」:你只儲存小數點後的小數部分 f,但硬體運作起來彷彿前面黏著一個 1.。你因此免費多賺到一個位元的尾數精度(雙精度中有效 53 位,實際只存 52 位)。正規化也讓每個數的表示唯一,這正是為何用簡單的整數比較位元樣式就能正確排列浮點數的大小。

正規化數涵蓋可表示集合的絕大部分,並賦予該格式其均勻的約 16 位相對精度。問題出在範圍的底部:最小的正規化雙精度數約為 2.2 * 10^(-308),而緊接其下,正規化網格會留下一道直落到零的突兀斷崖。為了緩和這道斷崖,標準在最小正規數之下加入「次正規數」——它們捨棄隱含的領先 1,以精度換取表示更接近零之值的能力,提供「漸進下溢」。

double 中的 6 為 1.5 * 2^2 = 二進位 1.1 * 2^2,是正規化形式:儲存的小數部分為 1000...0,儲存的(偏移)指數為 2 + 1023 = 1025;領先的 1 是隱含的,從不寫出。從約 2.2e-308 到約 1.8e308 的每個正規化雙精度數都帶有完整的 53 位精度。

領先 1 的約定買來一個免費的隱藏精度位元。

隱藏位元的技巧之所以可行,純粹因為基底 2 迫使領先數字必為 1;在比如十進位中就行不通。小到無法正規化的數會變成次正規數,所帶的有效位元「更少」。

又稱
normal numbernormalized number正規數