2012-08-06 75 views

回答

4

您的問題的答案是「否」。浮點數是(通常是*)用歸一化尾數和指數表示。乘法和除法首先在規範化的尾數上運行,然後在指數上運行。

加法和減法當然是另一回事。像你的例子一樣的操作:

567.56 + 345.54 or .00097854 - .00021297 

工作正常。但是運行的數量級別不一樣,如

567.56 + .00097854 or 345.54 - .00021297 

可能會失去一些低階精度。

+0

1994年,第一個奔騰出現了,並且在邏輯分區方面出現了缺陷。 http://en.wikipedia.org/wiki/Denormal_number這是玩笑。這是1994年的聖誕節,Andy Grove(英特爾的老闆)已經度過了不錯的一年。他走進一家酒吧,點了一杯27歲的單麥芽蘇格蘭威士忌來慶祝。調酒師說,「那將是20美元,先生。」格羅夫在酒吧上放了二十美元的鈔票,看了一會兒,然後說「保持變化」。 – 2012-08-06 22:07:30

+0

在音頻和其他信號處理應用中也會遇到非規格化數字,特別是在使用無限脈衝響應濾波器的情況下(如回波效應)。回波隨着時間的推移而減小,當輸入保持爲零時,回波最終達到非規格化的範圍。 – 2012-08-08 16:57:14

0

不需要。在某種意義上,無論數字的數量級(指數部分)是多少,都有相同的有效位數。

+0

這不完全正確。對於0x1p-126(浮點型)或0x1p-1022(雙精度型)下的數字,精度會有所下降。 – 2012-08-08 16:55:44

+0

@EricPostpischil你說得對,我忽略了那裏的低於正常水平的數字。然而,原始海報中的數字並不接近於低於正常水平,我想給出一個「簡單」的答案。 – 2012-08-08 17:02:36

1

對於IEEE 754二進制浮點數(最常見的),浮點值必須在有效數相同的比特數的在大部分指數範圍的。但是,有一部分範圍的有效位的有效位數較少。由舍入引起的相對誤差確實取決於有效位於其範圍內的位置。

IEEE 754浮點數用符號(+1或-1,編碼爲0或1)表示,指數(對於雙精度,-1022至1023,編碼爲指數加1023,so 1到2046)以及一個有效數字(對於雙精度,通常從1到不足2的分數,用53位表示,但用52位編碼,因爲第一位隱含地爲1)。例如,數字6.5用位0(符號+1),10000000001(指數2)和1010000000000000000000000000000000000000000000000000(二進制小數1.1010,十六進制1.a,十進制1.3125)編碼。我們可以將它寫成十六進制浮點數0x1.ap2(十六進制小數1.a乘以2的十進制數2)。用十六進制浮點寫入可以讓人類很容易地看到浮點表示。

對於指數,編碼值0和2047是特殊的。當編碼爲0時,指數與編碼爲1(-1022)時的指數相同,但分數的隱含位爲0而不是1.當編碼爲2047時,浮點對象表示無窮大(if有效位全部爲零)或NaN(否則)。

當編碼指數爲0且有效位全部爲零時,數字代表零(以符號區分+0和-0)。如果有效位不全爲零,則說該數字是非規格化的。這是因爲大多數數字都是通過調整指數來「歸一化」的,以便分數介於1(包含)和2(不包含)之間。對於非規格化的數字,分數小於1;它以「0」而不是「1」開始。

當浮點運算的結果是一個非規格化數時,它在有效數中有效地具有較少的位。因此,當數字低於0x1p-1022(2 -1022)時,有效精度下降。

當數字是在正常範圍內(未下溢到非正規數和不溢出到無窮大),則存在與不同的指數數字的有效數沒有差異,所以:

  • (2A + 2b)的/ 2與a + b具有完全相同的結果。
  • (2a-2b)/ 2與a-b具有完全相同的結果。
  • (2ab)/ 2與ab具有完全相同的結果。

但是請注意,相對誤差可能會改變。當執行浮點運算時,精確的數學結果必須舍入到可表示的值。這個四捨五入只能以有效數表示的單位發生。對於給定的指數,有效位中的位具有固定值。所以有效位中的最後一位代表了一定的值。該值是有效數值接近1的較大部分而不是有效數字接近2.

對於雙精度結果,最小精度(ULP)的單位是1的一部分在有效數字中最重要的一點。當使用圓到最近的模式(最常見的默認模式)時,最大誤差最多隻有一半,因爲如果一個方向上的可表示數量超過ULP的一半,那麼另一個方向上的數量就會減少遠遠超過一半ULP。接近的數字通過適當的浮點運算返回。

因此,與接近1的有效數的結果的最大相對誤差爲略微超過2 -53,但在與鄰近2有效數的結果的最大相對誤差在2 -54略。

1

爲了完整起見,我不得不同意了一下,說,它可能以某種重要...
事實上,如果執行56756.0/34554.0,那麼你會得到最接近的可表示浮點數到精確的數學結果,用單個浮點四捨五入「錯誤」。
這是因爲56756.0和34554.0完全可以在浮點(單精度或雙精度IEEE 754)中表示,並且由於根據IEEE 754標準,操作會執行精確的舍入操作(默認模式爲最近)。

如果你寫567.56/345.54,那麼這兩個數字都不是以浮點數2爲基數完全表示的,所以這個操作的結果是累積了3個浮點舍入「錯誤」。

讓我們比較結果佳樂Smalltalk中的雙精度(浮點數),轉換(在分子和分母分數任意整數長度),以精確的算法:

((56756.0/34554.0) asFraction - (56756/34554)) asFloat. 
-> -7.932275867322412e-17 

到目前爲止,一切都很好,幅度誤差小於或等於半ULP,由IEEE 754承諾:

(56756/34554) asFloat ulp/2 
-> 1.1102230246251565e-16 

隨着累積舍入誤差,可能會出現較大誤差(但從來沒有一個更小的):

((567.56/345.54) asFraction - (56756/34554)) asFloat 
-> -3.0136736359825544e-16 

((0.00056756/0.00034554) asFraction - (56756/34554)) asFloat 
-> 3.647664511768385e-16 

上面的例子很難概括,我完全同意其他答案:一般來說,你應該只關心相對精度。
...除非也許如果你想實現一些功能與非常嚴格的容忍關於四捨五入錯誤...