[英]IEEE754 float point substraction precision lost
這是減法
第一個數字
Decimal 3.0000002
Hexadecimal 0x4040001
Binary: Sign[0], Exponent[1000_0000], Mantissa[100_0000_0000_0000_0000_0001]
減去第二個數字:
Decimal 3.000000
Hexadecimal 0x4040000
Binary: Sign[0], Exponent[1000_0000], Mantissa[100_0000_0000_0000_0000_0000]
==========================================
在這種情況下,指數已經是相同的,我們只需要減去尾數即可。 我們知道在IEEE754中,尾數前面有一個隱藏位1。 因此,結果尾數應為:
Mantissa_1[1100_0000_0000_0000_0000_0001] - Mantissa_2[1100_0000_0000_0000_0000_0000]
等於
Mantissa_Rst = [0000_0000_0000_0000_0000_0001]
但是此數字未歸一化,因為第一個隱藏位不為1。因此,我們將Mantissa_Rst右移23次,並且指數同時減去23。
然后我們有結果值
Hexadecimal 0x4040000
Binary: Sign[0], Exponent[0110_1000], Mantissa[000_0000_0000_0000_0000_0000].
總共32位,無需舍入。
請注意,在尾數區域中仍存在一個隱藏的1。
如果我的計算是正確的,則將結果轉換為十進制數為0.00000023841858,與實際結果0.0000002相比,我仍然認為不是很精確。
所以問題是,我的計算錯誤嗎? 還是實際上這是真實情況,並且一直在計算機中發生?
誤差已經從您的輸入開始。 3.0000002
是分母中有一個素數為5的分數,因此它在基數2中的“十進制”展開是周期性的。 沒有數量的尾數就足以准確地表示它。 您提供的浮點數實際上具有值3.0000002384185791015625
(這是正確的)。 是的,這種情況一直發生。
但是不要失望! 以10為底的問題相同(例如1/3
)。 沒問題 好吧,這是針對某些人的,但幸運的是,還有其他一些數字類型可以滿足他們的需求。 浮點數具有很多優點,對於許多應用程序來說,略微的舍入誤差是無關緊要的,例如,即使您的輸入甚至不能完全精確地測量您感興趣的內容(許多科學計算和仿真)。 還請記住,也存在64位浮點數。 此外,錯誤是有界的:使用最佳舍入法,您的結果將在從無限精度結果中刪除的最后位置的 0.5個單位內。 以您的示例為單位的32位浮點數,大約為2^-25
或3 * 10 ^ -8。 當您執行一些必須舍入的附加操作時,情況將變得越來越糟,但是通過仔細的數值分析和正確的算法 ,您可以從中獲得很多好處。
只要x / 2≤y≤2x,則計算x-y就是精確的 ,這意味着沒有舍入誤差。 在您的示例中也是如此。
您只是錯誤地假設您的浮點數可能等於3.0000002。 你不能 “ float”類型只能表示小於2 ^ 24的整數乘以2的冪。 3.0000002不是這樣的數字,因此將其舍入為最接近於3.00000023841858的浮點數。 減3精確計算出差值,並得出接近0.00000023841858的結果。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.