2011-12-06 22 views
3

我使用Math.Round(1.7346, 2, AwayFromZero)這應該給我1,74 - 但它實際上給我1.73。回合1,7346至1,74

我知道那是因爲這個:

「由於精度,可能導致從代表 十進制值作爲浮點數或浮點值執行算術 經營虧損的,在有些情況下,Round(Double, Int32,MidpointRounding)方法可能不會出現在模式參數指定的中點 的值中,這在 下面的示例中進行了說明,其中2.135被舍入爲2.13而不是2.14 發生這種情況因爲內部方法將值乘以10 * 數字,並且在這種情況下的乘法操作會遭受 的精度損失。「

但是我應該使用哪種.NET方法來正確舍入?

+0

'MidpointRounding'纔會生效時以下你想要的數字的東西,就像是「50000」。對於其他情況,「Round」不辜負它的名稱 - 它將*舍入*到具有許多小數位的最接近的數字。 – cHao

回答

5

1.7346應該四捨五入到1.73,即使是AwayFromZero,因爲它只會改變舍入行爲,「當一個數字在另外兩個中間時」(例如,如果它已經是1.735)。

你想要的行爲可以通過

Math.Round(Math.Round(1.7346, 3, AwayFromZero), 2, AwayFromZero) 

獲得(但並不認爲這是什麼比黑客攻擊更)。

+0

謝謝 - 這是我現在嘗試和工作。 即使我有點困惑,因爲 1,7346應rouddet到1,735應該四捨五入至1,74 這就是我們期望至少在歐洲這裏? – user1083275

+3

@ user1083275 nope。當四捨五入到兩位十進制數字時,我們(歐洲人)只考慮前三位十進制數字,省略其餘的數字。在你的情況下,我們只是看看'1.734'並決定因爲'4'的四捨五入值爲1.73'。四捨五入你不需要多次迭代。當你四捨五入到十進制數字時,你的決定僅僅取決於'(n + 1)'十進制數字的值 – yas4891

+1

至少不在英國; 1.7346到2dp是1.73,因爲0.004輪下降,不起來 - 你不會繼續從最低有效位數開始四捨五入,直到你達到精度水平 –

1
Math.ceil() 

大紅大紫起來:)希望幫助

而作爲陳述.. 1.7345應該捨去..因爲1.7351會總結與Math.Round()。 所以,你必須知道你想要什麼..

Math.round() //Rounds 
Math.floor() //Rounds down 
Math.ceil() //Rounds up 
+1

Math.Ceil()不具有處理十進制數字的功能。你會從中得到一個「整數」值。 – yas4891

+0

不,Math.Ceiling可以處理雙精度和十進制類型..也在Ondrej Tucny的答案中說明..他是正確的:) – stackr

+0

'decimal'是一種存儲數字(帶有十進制數字)的方法。它與Math.Ceil()/ Math.Floor()等的行爲方式無關。看看MSDN中給出的例子:http://msdn.microsoft.com/en-us/library/1cz5da1c.aspx Ondrej說的是,你可以使用'Math.Floor/Math.Ceil'函數來創建(!)您自己的自定義舍入算法。這將涉及更多的算術。 – yas4891

1

你的假設是部分錯誤的。 1.7346四捨五入爲1.73,因爲AwayFromZero語義,即:

  • < 0.5→0.0
  • 0.5→1.0
  • > 0.5→1.0
  • < -0.5 -1.0→
  • - 0.5→-1.0
  • > -0.5→0.0

爲避免浮點運算引起的問題,使用decimal數據類型,該數據類型在小數數字系統方面是精確的。

要將「自定義」四捨五入到最近的較大或最近的較低數字,您可以分別使用Math.CeilingMath.Floor。它們都可用於doubledecimal類型。

0

我認爲Math.Round()這種方式的原因已被其他人解決。

另一種方式讓你期望的結果是增加0.005的值:

Math.Round(1.7346 + 0.005, 2, AwayFromZero)