二進制浮點數算術標準 IEEE 754

IEEE 754

維基百科,自由的百科全書

IEEE二進制浮點數算術標準IEEE 754)是1980年代以來最廣泛使用的浮點數運算標準,爲許多CPU浮點運算器所採用。這個標準定義了表示浮點數的格式(包括負零-0)與反常值(denormal number)),一些特殊數值(無窮非數值(NaN)),以及這些數值的“浮點數運算符”;它也指明瞭四種數值舍入規則和五種例外狀況(包括例外發生的時機與處理方式)。

IEEE 754規定了四種表示浮點數值的方式:單精確度(32位)、雙精確度(64位)、延伸單精確度(43比特以上,很少使用)與延伸雙精確度(79比特以上,通常以80比特實做)。只有32位模式有強制要求,其他都是選擇性的。大部分編程語言都有提供IEEE浮點數格式與算術,但有些將其列爲非必需的。例如,IEEE 754問世之前就有的C語言,現在有包括IEEE算術,但不算作強制要求(C語言的float通常是指IEEE單精確度,而double是指雙精確度)。

該標準的全稱爲IEEE二進制浮點數算術標準(ANSI/IEEE Std 754-1985),又稱IEC 60559:1989,微處理器系統的二進制浮點數算術(本來的編號是IEC 559:1989)[1]。後來還有“與基數無關的浮點數”的“IEEE 854-1987標準”,有規定基數爲2跟10的狀況。現在最新標準是“IEEE 854-2008標準”。

在六、七十年代,各家計算機公司的各個型號的計算機,有着千差萬別的浮點數表示,卻沒有一個業界通用的標準。這給數據交換、計算機協同工作造成了極大不便。IEEE的浮點數專業小組於七十年代末期開始醞釀浮點數的標準。在1980年,英特爾公司就推出了單片的8087浮點數協處理器,其浮點數表示法及定義的運算具有足夠的合理性、先進性,被IEEE採用作爲浮點數的標準,於1985年發佈。而在此前,這一標準的內容已在八十年代初期被各計算機公司廣泛採用,成了事實上的業界工業標準。

浮點數剖析

以下是該標準對浮點數格式的描述。

[編輯]本文表示比特的約定

把W個比特(bit)的數據,從內存地址低端到高端,以0到W−1編碼。通常將內存地址低端的比特寫在最右邊,稱作最低有效位(least significant bit或lsb),代表最小的比特,改變時對整體數值影響最小的比特。聲明這一點的必要性在於X86體系架構是小端序的數據存儲。

對於十進制整數N,必要時表示爲N10以與二進制的數的表示N2相區分。

對於一個數,其二進制科學計數法表示下的指數的值,下文稱之爲指數的實際值;而根據IEEE 754標準對指數部分的編碼的值,稱之爲浮點數表示法指數域的編碼值

[編輯]整體呈現

IEEE 754浮點數的三個域

二進制浮點數是以符號數值表示法的格式存儲——最高有效位被指定爲符號位(sign bit);“指數部份”,即次高有效的e個比特,存儲指數部分;最後剩下的f個低有效位的比特,存儲“尾數”(significand)的小數部份(在非規約形式下整數部份默認爲0,其他情況下一律默認爲1)。

[編輯]指數偏移值

指數偏移值(exponent bias),是指浮點數表示法中的指數域的編碼值爲指數的實際值加上某個固定的值,IEEE 754標準規定該固定值爲 2e-1 - 1[2],其中的e爲存儲指數的比特的長度。

以單精度浮點數爲例,它的指數域是8個比特,固定偏移值是28-1 - 1 = 128−1 = 127. 單精度浮點數的指數部分實際取值是從128到-127。例如指數實際值爲1710,在單精度浮點數中的指數域編碼值爲14410, 即14410 = 1710 + 12710.

採用指數的實際值加上固定的偏移值的辦法表示浮點數的指數,好處是可以用長度爲e個比特的無符號整數來表示所有的指數取值,這使得兩個浮點數的指數大小的比較更爲容易。

[編輯]規約形式的浮點數

如果浮點數中指數部分的編碼值在0 < exponent < 2^{e} - 1之間,且尾數部分最高有效位(即整數字)是1,那麼這個浮點數將被稱爲規約形式的浮點數

[編輯]非規約形式的浮點數

如果浮點數的指數部分的編碼值是0,尾數的最高有效位(即整數字)也是0,那麼這個浮點數將被稱爲非規約形式的浮點數。IEEE 754標準規定:非規約形式的浮點數的指數偏移值比規約形式的浮點數的指數偏移值大1. 例如,最小的規約形式的單精度浮點數的指數部分編碼值爲1,指數的實際值爲-126;而非規約的單精度浮點數的指數域編碼值爲0,對應的指數實際值也是-126而不是-127。實際上非規約形式的浮點數仍然是有效可以使用的,只是它們的絕對值已經小於所有的規約浮點數的絕對值;即所有的非規約浮點數比規約浮點數更接近0。規約浮點數的尾數大於等於1且小於2,而非規約浮點數的尾數小於1且大於0.

IEEE 754-1985標準採用非規約浮點數,源於70年代末IEEE浮點數標準化專業技術委員會醞釀浮點數二進制標準時,Intel公司漸進式下溢出(gradual underflow)的力薦。當時十分流行的DEC VAX機的浮點數表示採用了突然式下溢出(abrupt underflow). 如果沒有漸進式下溢出,那麼0與絕對值最小的浮點數之間的距離(gap)將大於相鄰的小浮點數之間的距離。例如單精度浮點數的絕對值最小的規約浮點數是1.0\times 2^{-126}, 它與絕對值次小的規約浮點數之間的距離爲2^{-126}\times 2^{-23}=2^{-149}。如果不採用漸進式下溢出,那麼絕對值最小的規約浮點數與0的距離是相鄰的小浮點數之間距離的2^{23}倍!可以說是非常突然的下溢出到0。這種情況的一種糟糕後果是:兩個不等的小浮點數X與Y相減,結果將是0. 訓練有素的數值分析人員可能會適應這種限制情況,但對於普通的程序員就很容易陷入錯誤了。採用了漸進式下溢出後將不會出現這種情況。例如對於單精度浮點數,指數部分實際最小值是(-126),對應的尾數部分從1.1111\ldots 111.1111\ldots 10一直到0.0000\ldots 020.0000\ldots 01,相鄰兩小浮點數之間的距離(gap)都是2^{-126}\times 2^{-23}=2^{-149};而與0最近的浮點數(即最小的非規約數)也是2^{-126}\times 2^{-23}=2^{-149}

[編輯]特殊值

這裏有三個特殊值需要指出:

  1. 如果 指數 是0 並且尾數的 小數部分 是0,這個數±0(和符號位相關)
  2. 如果 指數 = 2^{e} - 1 並且尾數的 小數部分 是0,這個數是 ±(同樣和符號位相關)
  3. 如果 指數 = 2^{e} - 1 並且尾數的 小數部分 非0,這個數表示爲不是一個數(NaN)

以上規則,總結如下:

形式 指數 小數部分
0 0
非規約形式 0 非0
規約形式 1 到 2^e-2 任意
無窮 2^e-1 0
NaN 2^e-1 非零

[編輯]32位單精度

單精度二進制小數,使用32個比特存儲。

1 8 23 位長
S Exp Fraction
31 3023
偏正值 (實際的指數大小+127)
220 位編號(從右邊開始爲0)

S爲符號位,Exp爲指數字,Fraction爲有效數字。 指數部分即使用所謂的偏正值形式表示,偏正值爲實際的指數大小與一個固定值(32位的情況是127)的和。採用這種方式表示的目的是簡化比較。因爲,指數的值可能爲正也可能爲負,如果採用補碼錶示的話,全體符號位S和Exp自身的符號位將導致不能簡單的進行大小比較。正因爲如此,指數部分通常採用一個無符號的正數值存儲。單精度的指數部分是−126~+127加上偏移值127 ,指數值的大小從1~254(0和255是特殊值)。浮點小數計算時,指數值減去偏正值將是實際的指數大小。

單精度浮點數各種極值情況:

類別 正負號 實際指數 有偏移指數 指數域 尾數域 數值
0 -127 0 0000 0000 000 0000 0000 0000 0000 0000 0.0
負零 1 -127 0 0000 0000 000 0000 0000 0000 0000 0000 −0.0
1 0 0 127 0111 1111 000 0000 0000 0000 0000 0000 1.0
-1 1 0 127 0111 1111 000 0000 0000 0000 0000 0000 −1.0
最小的非規約數 * -126 0 0000 0000 000 0000 0000 0000 0000 0001 ±2−23 × 2−126 = ±2−149 ≈ ±1.4×10-45
中間大小的非規約數 * -126 0 0000 0000 100 0000 0000 0000 0000 0000 ±2−1 × 2−126 = ±2−127 ≈ ±5.88×10-39
最大的非規約數 * -126 0 0000 0000 111 1111 1111 1111 1111 1111 ±(1−2−23) × 2−126 ≈ ±1.18×10-38
最小的規約數 * -126 1 0000 0001 000 0000 0000 0000 0000 0000 ±2−126 ≈ ±1.18×10-38
最大的規約數 * 127 254 1111 1110 111 1111 1111 1111 1111 1111 ±(2−2−23) × 2127 ≈ ±3.4×1038
正無窮 0 128 255 1111 1111 000 0000 0000 0000 0000 0000 +∞
負無窮 1 128 255 1111 1111 000 0000 0000 0000 0000 0000 −∞
NaN * 128 255 1111 1111 non zero NaN
* 符號位可以爲0或1 .

[編輯]64位雙精度

雙精度二進制小數,使用64個比特存儲。

1 11 52 位長
S Exp Fraction
63 6252
偏正值 (實際的指數大小+1023)
510 位編號(從右邊開始爲0)

S 爲符號位,Exp爲指數字,Fraction爲有效數字。 指數部分即使用所謂的偏正值形式表示,偏正值爲實際的指數大小與一個固定值(64位的情況是1023)的和。採用這種方式表示的目的是簡化比較。因爲,指數的值可能爲正也可能爲負,如果採用補碼錶示的話,全體符號位S和Exp自身 的符號位將導致不能簡單的進行大小比較。正因爲如此,指數部分通常採用一個無符號的正數值存儲。雙精度的指數部分是−1022~+1023加上1023 ,指數值的大小從1~2046(0(2進位全爲0)和2047(2進位全爲1)是特殊值)。浮點小數計算時,指數值減去偏正值將是實際的指數大小。

[編輯]浮點數的比較

浮點數基本上可以按照符號位、指數域、尾數域的順序作字典比較。顯然,所有正數大於負數;正負號相同時,指數的二進制表示法更大的其浮點數值更大。

[編輯]浮點數的舍入

任何有效數上的運算結果,通常都存放在較長的暫存器中,當結果被放回浮點格式時,必須將多出來的比特丟棄。 有多種方法可以用來運行舍入作業,實際上IEEE標準列出4種不同的方法:

  • 舍入到最接近:會將結果舍入爲最接近且可以表示的值。這是缺省的近似方法。
  • 朝+∞方向舍入:會將結果朝正無限大的方向舍入。
  • 朝-∞方向舍入: 會將結果朝負無限大的方向舍入。
  • 朝0方向舍入: 會將結果朝0的方向舍入。

[編輯]浮點數的運算與函數

[編輯]標準運算

下述函數必須提供:

  • 加減乘除 Add, subtract, multiply, divide
  • 平方根 Square root
  • 浮點餘數. 返回值 x-(round(x/y)*y).
  • 近似到最近的整數. 如果恰好在兩個相鄰整數之間,則近似到偶數.
  • 比較運算. IEEE754定義了特殊情況: -inf = -inf, inf = inf and x ≠ NaN for any x (including NaN).

[編輯]建議的函數與謂詞

  • Under some C compilers, copysign(x,y) returns x with the sign of y, so abs(x) equals copysign(x,1.0). This is one of the few operations which operates on a NaN in a way resembling arithmetic. The function copysign is new in the C99 standard.
  • −x returns x with the sign reversed. This is different from 0−x in some cases, notably when x is 0. So −(0) is −0, but the sign of 0−0 depends on the rounding mode.
  • scalb(y, N)
  • logb(x)
  • finite(x) a predicate for "x is a finite value", equivalent to −Inf < x < Inf
  • isnan(x) a predicate for "x is a nan", equivalent to "x ≠ x"
  • x <> y which turns out to have different exception behavior than NOT(x = y).
  • unordered(x, y) is true when "x is unordered with y", i.e., either x or y is a NaN.
  • class(x)
  • nextafter(x,y) returns the next representable value from x in the direction towards y

[編輯]外部鏈接


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章