2014-12-05 102 views
0

我試圖截斷C#中的一系列雙精度值。無論使用什麼舍入方法,以下值都會失敗。這個值導致這兩種方法失敗的問題是什麼?爲什麼即使Math.Round未能正確截斷數字?可以使用什麼方法來正確截斷這些值?舍入到specfic數字失敗,這個雙精度值

值:

double value = 0.61740451388888251; 

方法1:

return Math.Round(value, digits); 

方法2:

double multiplier = Math.Pow(10, decimals) 
return Math.Round(value * multiplier)/multiplier; 

即使在VS觀看無線失敗ndow!

round

+1

浮點類型不能代表所有可能的值,這意味着這大概是0.62儘可能最接近。 – 2014-12-05 19:45:59

+1

爲什麼downvote?這是一個非常令人困惑的問題,絕不是初學者的問題。你不明白這個問題的前提嗎? – 2014-12-05 19:46:54

+0

@JordiVermeulen - 'double'肯定可以正確表示0.62。 – 2014-12-05 19:47:37

回答

4

雙是一個浮動二進制點類型。它們以二進制形式表示(如11010.00110)。當double以十進制表示時,它只是一個近似值,因爲並非所有的二進制數都有十進制的精確表示。嘗試例如此操作:

double d = 3.65d + 0.05d; 

它不會導致3.73.6999999999999997。這是因爲變量包含最接近的可用double

您的情況也是如此。您的變量包含最接近的可用double

對於精確操作double/float不是最幸運的選擇。 當您需要快速性能或者您想要在更大範圍的數字上操作時,使用double/float,但不需要高精度。例如,它是物理計算的完美類型。 精確的小數運算使用,以及decimal

這裏是關於float/decimal的文章:http://csharpindepth.com/Articles/General/FloatingPoint.aspx

0

我認爲你是對一個雙精度浮點(64位)的二進制極限跑起來。從http://en.wikipedia.org/wiki/Double-precision_floating-point_format,雙重只給出15-17個有效數字。

+0

爲什麼'Math.Round'無法正確截斷數字?什麼方法可以用來代替? – 2014-12-05 19:58:37

+0

你只是想四捨五入到小數點後兩位? – ryanyuyu 2014-12-05 20:02:27

+0

由於您使用的是C#,因此可以使用Decimal類。 http://msdn.microsoft.com/en-us/library/System.Decimal(v=vs.110).aspx – ryanyuyu 2014-12-05 20:07:18

3

根據這個在線工具,它使雙打的二進制表示,以0.62最接近的兩個雙值:

6.19999999999999995559107901499E-10x3FE3D70A3D70A3D7 link

6.20000000000000106581410364015E-10x3FE3D70A3D70A3D8 link

我我不確定爲什麼這些都不能完全符合你的價值,但正如其他人說的那樣,這可能是一個浮點表示問題。

3

如果您需要更準確地表示數字,您可能必須使用decimal類型,該類型具有更高的精度但範圍更小(通常用於財務計算)。關於何時使用每個這裏

更多信息:https://stackoverflow.com/a/618596/1373170