我使用小數類型進行高精度計算(貨幣)。小數的精度
但我今天碰到這個簡單的除法就來了:
1/(1/37)
這將導致37再次
http://www.wolframalpha.com/input/?i=1%2F+%281%2F37%29
但是C#給我: 37.000000000000000000000000037M
我想這兩個: 1m/(1m/37m);
和 Decimal.Divide(1, Decimal.Divide(1, 37))
但都產生相同的結果。行爲如何解釋?
我使用小數類型進行高精度計算(貨幣)。小數的精度
但我今天碰到這個簡單的除法就來了:
1/(1/37)
這將導致37再次
http://www.wolframalpha.com/input/?i=1%2F+%281%2F37%29
但是C#給我: 37.000000000000000000000000037M
我想這兩個: 1m/(1m/37m);
和 Decimal.Divide(1, Decimal.Divide(1, 37))
但都產生相同的結果。行爲如何解釋?
Decimal
將該值存儲爲十進制浮點值,並且精度有限。由於1/37的結果存儲爲0.027027027027027027027027027M,因此不會預先存儲。真正的數字組027無限期地以十進制表示。因此,對於每個可能的數字,您都無法獲得十進制表示的精確數字。
如果在同一計算中使用Double
,則在這種情況下最終結果是正確的(但這並不意味着它總是會更好)。
有關該主題的一個很好的答案就在這裏:Difference between decimal, float and double in .NET?
十進制數據類型有28-29顯著數字的準確性。 所以你必須明白的是,當你考慮28-29個重要數字時,你仍然不確切。
所以,當你計算(1/37)的十進制值時,你必須注意的是,在這個階段你只能得到28-29位數的精確度。例如,當您獲取2位有效數字時,1/37爲0.02,當您獲取3位有效數字時爲0.027。想象一下,在每種情況下,用這些值除1。在第一種情況下得到50,在第二種情況下得到37.02 ...考慮28-29數字(十進制)會使您的準確度達到37.000000000000000000000000037。如果你必須得到一個確切的37,你只需要比十進制提供的有效數字多28-29。
始終使用最大有效位數進行計算,並只用Math.Round對您的答案進行四捨五入以獲得所需結果。
更多信息:http://stackoverflow.com/questions/618535/what-is-the-difference-between-decimal-float-and-double-in-c?rq=1 –
我想你應該看看http://msdn.microsoft.com/en-us/library/364x0z75.aspx - 十進制不會採取(1/37)並將其表示爲分子/分母成員。它只是一個數量更大,範圍更小的數字,這使得它更適合於某些計算。越小的範圍和更大的尺寸意味着小數具有更高的精度。 – Warty
[每個程序員應該知道什麼關於浮點運算](http://floating-point-gui.de/) –