任何人都可以解釋這一點嗎?C#十進制分區(非常奇怪的行爲)
Decimal leftSide = 13.0M;
Decimal rightSide = 1.0M;
Decimal tmpDec = 39.0M;
tmpDec * (rightSide/leftSide) = 2.9999999999999999999999999991
tmpDec * rightSide/leftSide = 3
我在第一個(右側/左側)失去了有效數字嗎?
任何人都可以解釋這一點嗎?C#十進制分區(非常奇怪的行爲)
Decimal leftSide = 13.0M;
Decimal rightSide = 1.0M;
Decimal tmpDec = 39.0M;
tmpDec * (rightSide/leftSide) = 2.9999999999999999999999999991
tmpDec * rightSide/leftSide = 3
我在第一個(右側/左側)失去了有效數字嗎?
這是四捨五入(鬆動精度)的問題。
第一種情況首先執行除法並裁剪最後一個數字(自float(或double或decimal或任何其他固定精度數據類型)以來不能存儲無限長值的小數點後的第28位),然後執行裁剪的價值增加了3900萬次的損失。這已經變得很重要(現在不是28位數字問題,堅果20-22)並且不能捨入到3.0。
第二種情況首先執行乘法,不放寬精度並存儲每8位數字,然後以較小的精度寬鬆(小數點後6位)執行除法。因此在第一種情況下已經舍入到3.0而不是2.999999999999999999999。
十進制類型僅精確到29位有效數字。
2.9999999999999999999999999991
^擁有超過29個顯著數字。
如果您需要更高的精度,您可以使用System.Numerics.BigInteger(將其修改爲定點小數)。
使用.NET 3.5,謝謝你的答案。 – 2013-04-10 12:41:01
將無限多個實數擠壓成有限數量的比特需要近似表示。雖然有無限多的整數,但在大多數程序中,整數計算的結果可以存儲在32位中。相反,給定任意固定的位數,大多數使用實數的計算都會產生無法使用多位來精確表示的數量。因此,浮點計算的結果必須經過四捨五入以適應其有限表示。這個舍入誤差是浮點運算的特徵
[每個計算機科學家應該知道的關於浮點運算的內容](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg .html) – Habib 2013-04-10 12:31:51
謝謝你的白皮書鏈接。 – 2013-04-10 12:45:20