(完成)若要了解 IEEE 浮點數錯誤的教學課程

文章翻譯 文章翻譯
文章編號: 42980 - 檢視此文章適用的產品。
全部展開 | 全部摺疊

在此頁中

結論

浮點數學是複雜的主題,混淆許多程式設計人員。下列教學課程應該可以幫助您辨識程式設計浮點數的錯誤是可能發生的情況下,以及如何避免它們。它也應該讓您辨識所造成的相對於實際的編譯器錯誤固有的浮點數學限制的情況。

其他相關資訊

十進位和二進位數字系統

通常,我們計算基底為 10 的事情。基底為完全任意。人傳統上已使用基底為 10 的唯一原因是它們做了很方便的計算工具的 10 個手指。

十進位 (基底 10) 的 532.25 數表示下列:
   (5 * 10^2) + (3 * 10^1) + (2 * 10^0) + (2 * 10^-1) + (5 * 10^-2)
       500    +     30     +      2     +     2/10    +    5/100
   _________
   =  532.25
				

在二進位數字系統 (基底 2) 中,每個資料行代表 2 代替 10 的乘冪。比方說編號 101.01 表示下列:
   (1 * 2^2) + (0 * 2^1) + (1 * 2^0) + (0 * 2^-1) + (1 * 2^-2)
       4     +      0    +     1     +      0     +    1/4
   _________
   =  5.25  Decimal
				

整數在個人電腦中的表現方式

因為沒有小數部分為整數其機器] 表示就會是更簡單,比浮點值。在個人電腦 (PC) 上的一般整數長時間與最重要指出正負號的位元是 2 個位元組 (16 位元)。長整數是 4 個位元組。 正值是簡單的二進位數字。例如:
    1 Decimal = 1 Binary
    2 Decimal = 10 Binary
   22 Decimal = 10110 Binary, etc.
				

不過,負整數會表示使用二的補數配置。若要設法二的補數表示負數採取二進位表示的數字的絕對值,然後翻轉所有位元並新增 1。例如:
   4 Decimal = 0000 0000 0000 0100
               1111 1111 1111 1011     Flip the Bits
   -4        = 1111 1111 1111 1100     Add 1
				

請注意該-1 Decimal = 1111年 1111年 1111年 1111 二進位,在其中解釋 Basic 為何-1 視為邏輯則為 True (所有位元 = 1)。這是不讓個別運算子的位元和邏輯比較的結果。通常在 Basic,很方便使用的程式碼片段底下時您的程式將會使許多邏輯比較。這大大幫助可讀性。
   CONST TRUE = -1
   CONST FALSE = NOT TRUE
				

請注意,加入兩個的任何組合互補數字一起使用一般的二進位算術運算會產生正確的結果。

浮點數的複雜情形

每個十進位整數可以完全表示由二進位整數 ; 但,這並不適用小數的數字。在實際上是在基底 10 irrational 每逢個數字也會是 irrational 小於 10 的基底任何系統中。

之二進位檔,在特別只有小數的數字,可以用來表示在表單 p/q,其中 q 是 2 的整數方,可以表示完全,使用有限位元數。

例如十進位 0.0001 甚至常見十進位小數不能完全以二進位表示。(0.0001 是以句點 104 位元的重複二進位小數)!

這解釋為何一個簡單的範例如下所示
   SUM = 0
   FOR I% = 1 TO 10000
      SUM = SUM + 0.0001
   NEXT I%
   PRINT SUM                   ' Theoretically = 1.0.
				

將輸出為 PRINT 1.000054。中代表以二進位 0.0001 小錯誤傳播到總和。

因相同原因而永遠時應該要非常小心實數上進行比較。下列範例說明常見的程式設計錯誤:
   item1# = 69.82#
   item2# = 69.20# + 0.62#
   IF item1# = item2# then print "Equality!"
				

這不會因為不能完全以會使所產生工作分派會稍有不同 (以二進位) 值的二進位表示 69.82 PRINT"相等]! 比從運算式產生的值。在練習中,您應該永遠程式碼以允許某些容錯的一種這類比較。例如:
   IF (item1# < 69.83#) AND (item1# > 69.81#) then print "Equal"
				

這將 PRINT 「 相等 」。

IEEE 格式的數字

MS-DOS 版本 3.0 的 QuickBasic 出貨與較 MBF (Microsoft 二元浮動點) 的版本和數學副處理器的機器是 IEEE (電機電子電機工程師) 版本。如 MS-DOS QuickBasic,4.0 版及更新版本只使用 IEEE。Microsoft 選擇 IEEE 標準,代表在目前版本的基本的浮點值基於下列三個主要原因:
  1. 若要允許使用 Intel 數學 coprocessors 哪一種使用 IEEE 格式的基本。Intel 80 x 87 數列 coprocessors 不能使用 Microsoft 二進位格式的數字。
  2. 使 interlanguage 呼叫 Basic、 C、 Pascal 命名法、 FORTRAN 和 MASM 之間更容易。否則,轉換常式必須用來將數字值從一種語言傳送至另一個。
  3. 若要達到一致性。IEEE 是可接受的工業標準的 C 和 FORTRAN 編譯器。
以下是快速比較的雙精度數字的 IEEE 及 MBF 表示法:
               Sign Bits   Exponent Bits   Mantissa Bits
               ---------   -------------   -------------
   IEEE        1           11              52 + 1 (Implied)
    MBF        1            8              56
				

如需有關 IEEE 及 MBF 浮點表示,查詢 「 Microsoft 知識庫 」 中下列字之間差異的詳細資訊:
   IEEE and floating and point and appnote
				

請注意 IEEE 有更多位元專用指數允許它代表一個更廣泛範圍的值。MBF 有更多位的尾數元讓它成為更精確窄的範圍內。

一般的浮點概念

務必要實現任何二進位浮點系統可以表示只有有限數量的確切的表單中的浮點數值。其他所有值必須都近似傳最接近的表示值。IEEE 標準指定捨入值接近 」 表示值的方法。MS-DOS 的 QuickBasic 支援標準,並根據 IEEE 規則來將捨入。

而且,請記住,IEEE 中可以表示的數字展現非常廣泛的範圍內。您可以想像它們數行上。高密度表示的數字附近 1.0 和-1.0 但您最最當您移向 [0] 或 [無限大。

IEEE 標準其的工程計算設計用的目標是要最大化命中率 (若要取得盡可能以實際關閉編號)。精確度指的是可以代表的數字數目。IEEE 標準會嘗試之間取得平衡的位元數專用指數用於數字的小數部分,以保持正確性與可接受的限制內的精確度位元數。

IEEE 詳細資料

浮點的數字是以下列形式其中 [指數] 是二進位指數表示:
   X =  Fraction * 2^(exponent - bias)
				

[分數] 是正規化分數一部分數正規化因為指數已調整,以便前置字元的位元恆為 1。如此一來它不具有被儲存,且取得一個更多的位元的精確度。這是為什麼隱含位元。您可以把這像科學標記法您用來操作指數除了有在小數點左邊的一個數字的二進位,您永遠可以操作指數,,使第一個位元為 1 因為有唯一 1s 和 0。

[偏差] 是用來避免儲存負指數的偏差值。

單精度數字的偏差是 127 和雙精度數字 (十進位) 的 1023年。

值等於所有 0,所有 1 的 (二進位) 都保留給代表特殊情況。有其他特殊情況同時也會指出各種錯誤情況。

單精度範例

2 = 1 * 2 ^1 = 0100年 0000 0000 0000...0000 0000 = 4000 0000 十六進位
請注意正負號位元為零,和預存的指數為 128,或 100 0000 0 的二進位,也就是 127 加 1。儲存的尾數是 (1) 000 0000...具有隱含的前置字元 1 和二進位的 0000 0000 點,因此實際的尾數為 1。

-2 =-1 * 2 ^1 = 1100年 0000 0000 0000...0000 0000 = C000 0000 十六進位
相同為 + 2,不同之處在於已設定正負號位元。是如此所有 IEEE 格式浮點數字。

4 = 1 * 2 ^2 = 0100年 0000 1000年 0000...0000 0000 = 4080 0000 十六進位
相同的尾數指數增加的其中一個 (偏差結果的值為 129,或 100 0000 1 的二進位檔中。

6 = 1.5 * 2 ^2 = 0100年 0000 1100年 0000...0000 0000 = 40 C 0 0000 十六進位
相同指數尾數是較大的半--它是 100 (1) 0000...這由於這是二進位分數是 1-1/2 的 0000 0000 (小數位數的值為 1/2、 1/4、 1/8 等等)。

1 = 1 * 2 ^0 = 0011 1111年 1000年 0000...0000 0000 = 3F80 0000 十六進位
為其他的 2 的次方的相同指數,假數是一個小於 2 127,或 011 1111年 1 的二進位檔中。

.75 = 1.5 * 2 ^-1 = 0011 1111年 0100年 0000...0000 0000 = 3F40 0000 十六進位
偏誤的指數是 126,011 1111年 0 的二進位檔和假數是 100 (1) 0000...也就是 1-1/2 的 0000 0000。

2.5 = 1.25 * 2 ^1 = 0100年 0000 0010 0000...0000 0000 = 4020 0000 十六進位
完全相同 2 除外,如用來代表 1/4 會設定位元假數中。

0.1 = 1.6 * 2 ^-4 = 0011 1101年...1100年 1100年 1100年 1101年 = 3DCC CCCD 十六進位
1/10 是二進位檔中的重複分數。假數只害羞的 1.6,且偏差結果的指數 」 說明 1.6 是以除以 16 (它是 011 1101年是 123 (十進位格式的二進位 1)。則為 True 的指數為 123 127 =-4 這表示所用相乘的因數為 2 貴-4 = 1/16。請注意儲存的尾數在最後一個位元會進位。這是嘗試儘精確表示無法表示數字。(原因 1/10 」 和 「 1/100 比較不完全的二進位表示類似於 1/3 是不完全十進位格式表示的方法)

0 = 1.0 * 2 ^-128 = 所有零--特殊案例。

其他常見的浮點錯誤

以下是常見的浮點錯誤:
  1. 無條件捨去錯誤

    所有位元二進位數字中不能被用於計算時,就會產生這個錯誤。

    範例: 新增至 0.0001 0.9900 (單一整數位數)

    十進位 0.0001 會表示為:
    (1) 10100011011011100010111 * 2^(-14+bias) (13 前置 0 的二進位)!
    0.9900 會表示為:
    (1) 11111010111000010100011 * 2^(-1+bias)。
    現在實際上將這些數字相加,必須對齊小數點 (二進位) 點。為此它們必須是 Unnormalized。以下是產生加法:
           .000000000000011010001101 * 2^0  <- Only 11 of 23 Bits retained
          +.111111010111000010100011 * 2^0
          ________________________________
           .111111010111011100110000 * 2^0
    
    						
    這稱為無條件捨去的錯誤,因為有些電腦四捨五入時移位加法。其他人只是截斷。四捨五入-關閉錯誤很重要考慮每當您新增或乘以兩個非常不同的值。
  2. 減去兩個幾乎等於值
           .1235
          -.1234
           _____
           .0001
    
    						
    這將會被正常化。請注意雖然原始號碼每個有四個有效位數,結果有只能有一個有效位數。
  3. 溢位和反向溢位

    結果太大或太小,無法由資料型別時,就會發生這種情況。
  4. quantizing 錯誤

    就會發生這個問題與不精確的表單以浮點數的標準表示那些數字。
  5. 非常少數的除數

    這可以觸發一個 「 除以零 」 的錯誤,或者可能會產生下列範例中的錯誤結果:
          A = 112000000
          B = 100000
          C = 0.0009
          X = A - B / C
    
    						
    在 QuickBasic 為 X 現在的 MS-DOS 具有值 888887,正確答案 900000 代替。
  6. 輸出錯誤

    當輸出函式改變他們正在使用的值時,就會發生這種類型的錯誤。

屬性

文章編號: 42980 - 上次校閱: 2005年8月16日 - 版次: 3.1
這篇文章中的資訊適用於:
  • Microsoft Visual Basic 2.0 Standard Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Standard Edition
  • Microsoft Visual Basic 1.0 Standard Edition
  • Microsoft Visual Basic 2.0 Professional Edition
  • Microsoft Visual Basic 3.0 Professional Edition
  • Microsoft Visual Basic 4.0 Professional Edition
  • Microsoft Visual Basic for MS-DOS
  • Microsoft QuickBasic 4.0
  • Microsoft QuickBASIC 4.0b
  • Microsoft QuickBasic 4.5 for MS-DOS
  • Microsoft BASIC Compiler 6.0
  • Microsoft BASIC Compiler 6.0b
  • Microsoft BASIC Professional Development System 7.0
  • Microsoft 電影年鑑 97 Standard Edition
關鍵字:?
kbmt KB42980 KbMtzh
機器翻譯
重要:本文是以 Microsoft 機器翻譯軟體翻譯而成,而非使用人工翻譯而成。Microsoft 同時提供使用者人工翻譯及機器翻譯兩個版本的文章,讓使用者可以依其使用語言使用知識庫中的所有文章。但是,機器翻譯的文章可能不盡完美。這些文章中也可能出現拼字、語意或文法上的錯誤,就像外國人在使用本國語言時可能發生的錯誤。Microsoft 不為內容的翻譯錯誤或客戶對該內容的使用所產生的任何錯誤或損害負責。Microsoft也同時將不斷地就機器翻譯軟體進行更新。
按一下這裡查看此文章的英文版本:42980
Microsoft及(或)其供應商不就任何在本伺服器上發表的文字資料及其相關圖表資訊的恰當性作任何承諾。所有文字資料及其相關圖表均以「現狀」供應,不負任何擔保責任。Microsoft及(或)其供應商謹此聲明,不負任何對與此資訊有關之擔保責任,包括關於適售性、適用於某一特定用途、權利或不侵權的明示或默示擔保責任。Microsoft及(或)其供應商無論如何不對因或與使用本伺服器上資訊或與資訊的實行有關而引起的契約、過失或其他侵權行為之訴訟中的特別的、間接的、衍生性的損害或任何因使用而喪失所導致的之損害、資料或利潤負任何責任。
依現狀不再更新的知識庫內容免責聲明
本文旨在說明 Microsoft 不再提供支援的產品。因此,本文係依「現狀」提供,不會再更新。

提供意見

 

Contact us for more help

Contact us for more help
Connect with Answer Desk for expert help.
Get more support from smallbusiness.support.microsoft.com