回答
您的問題的答案是「否」。浮點數是(通常是*)用歸一化尾數和指數表示。乘法和除法首先在規範化的尾數上運行,然後在指數上運行。
加法和減法當然是另一回事。像你的例子一樣的操作:
567.56 + 345.54 or .00097854 - .00021297
工作正常。但是運行的數量級別不一樣,如
567.56 + .00097854 or 345.54 - .00021297
可能會失去一些低階精度。
- IEEE浮點標準包括非規格化數字。如果您是天體物理學家或運行時庫開發人員,您可能需要了解他們。見http://en.wikipedia.org/wiki/Denormal_number
1994年,第一個奔騰出現了,並且在邏輯分區方面出現了缺陷。 http://en.wikipedia.org/wiki/Denormal_number這是玩笑。這是1994年的聖誕節,Andy Grove(英特爾的老闆)已經度過了不錯的一年。他走進一家酒吧,點了一杯27歲的單麥芽蘇格蘭威士忌來慶祝。調酒師說,「那將是20美元,先生。」格羅夫在酒吧上放了二十美元的鈔票,看了一會兒,然後說「保持變化」。 – 2012-08-06 22:07:30
在音頻和其他信號處理應用中也會遇到非規格化數字,特別是在使用無限脈衝響應濾波器的情況下(如回波效應)。回波隨着時間的推移而減小,當輸入保持爲零時,回波最終達到非規格化的範圍。 – 2012-08-08 16:57:14
不需要。在某種意義上,無論數字的數量級(指數部分)是多少,都有相同的有效位數。
這不完全正確。對於0x1p-126(浮點型)或0x1p-1022(雙精度型)下的數字,精度會有所下降。 – 2012-08-08 16:55:44
@EricPostpischil你說得對,我忽略了那裏的低於正常水平的數字。然而,原始海報中的數字並不接近於低於正常水平,我想給出一個「簡單」的答案。 – 2012-08-08 17:02:36
對於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略。
爲了完整起見,我不得不同意了一下,說是,它可能以某種重要...
事實上,如果執行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
上面的例子很難概括,我完全同意其他答案:一般來說,你應該只關心相對精度。
...除非也許如果你想實現一些功能與非常嚴格的容忍關於四捨五入錯誤...
- 1. 計算浮點數上的精確值的最大位數
- 2. 讀浮點值,而不會失去包含浮點數字值,如精度
- 3. 浮點數不精確
- 4. 檢查數字是否精確浮點數(int)或實際浮點數
- 5. 確定浮點數是否是另一個浮點數的倍數?
- 6. 浮點數計算
- 7. 高精度打印結果(浮點數)
- 8. 什麼是浮點數的「偏差值」?
- 9. 精確到浮點小數?
- 10. 檢查兩個浮點數/雙精度值是否相等
- 11. 數學計算 - 浮點數
- 12. 浮點運算和浮點值比較
- 13. 檢查一個變量是否是雙精度浮點數
- 14. 精確值的雙/浮點比較
- 15. c# - 計算器 - 用浮點數計算
- 16. MongoDB浮點值精度?
- 17. 浮點不精確printf/appendFormat
- 18. php計算浮點數
- 19. 如果所有位都是0,那麼IEEE浮點的值是多少?
- 20. 如何檢查值是否是javascript中的浮點數
- 21. 計算整數和一個浮點數
- 22. 用負浮點值計算比例
- 23. 編寫0.0,0.0f或.0f而不是簡單的0爲假設的浮點數或雙精度值是否更好
- 24. 返回浮點而不是整數
- 25. SQL服務器計算返回0,而不是一個浮點值
- 26. 「複數浮點」和「浮點複數」是否都有效C?
- 27. 單精度大端浮點值到Python浮點數(雙精度,大端)
- 28. 雙精度浮點數和其他浮點數精度
- 29. 是否可以在文字地址處更改浮點數(值)?
- 30. 浮點計數爲零時不是
我認爲*較低的值更準確 - 但它已經有一段時間,因爲我不得不擔心關於這種事情。運行一些實驗來了解。 – ChrisF 2012-08-06 21:54:41