2013-11-01 87 views
1

有人可以向我解釋爲什麼Math.Round(1.565,2) = 1.56而不是1.57Math.Round數字,3位小數

+1

在這裏看到:http://stackoverflow.com/questions/977796/why-does-math-round2-5-return-2-instead-of-3-in-c –

+1

你能否詳細說明這兩種語言在這裏如何應用? –

+0

'Math.Round(1.565,2,MidpointRounding.AwayFromZero)'會給你'1.57' –

回答

1

參見:Math.Round Method (Double, Int32)

由於損失的精度,可能導致從代表 十進制值作爲浮點數或浮點值進行算術 操作,在某些情況下,圓形的(Double, Int32)方法可能不會出現將中點值舍入到最接近的 偶數值的小數點位置。這在以下示例中的 中進行了說明,其中2.135被舍入爲2.13而不是2.14。 發生這種情況的原因是內部方法會將值乘以10位數,並且在這種情況下乘法運算會遇到 丟失的精度。

而且例子是:

public static void Main() 
    { 
     double[] values = { 2.125, 2.135, 2.145, 3.125, 3.135, 3.145 }; 
     foreach (double value in values) 
     Console.WriteLine("{0} --> {1}", value, Math.Round(value, 2)); 

    } 
1

1.565的double表示不準確,並且略微小於該數量 - 1.56499999999999994670929481799249960965709294817992486059665679931640625或其附近。所以當四捨五入到小數點後兩位時,它會向下舍入。

即使你使用decimal(代表小數完全一致),並嘗試Math.round(1.565M,2),這也將得到四捨五入,如Math.round(number, decimalPlaces)回合值一個值和未來走向最後的數字是連一個之間的中途 - 這有時稱爲banker's rounding。例如,Math.round(1.575M,2)將向上舍入。

+0

從我在評論中發佈的鏈接中,我認爲這個「錯誤」實際上是C#的一個名爲Banker's Rounding的特性。 –

+1

@ SamuelO'Malley兩人都在某些情況下發揮作用。如果「double」*能夠精確地表示數值,則使用銀行家的舍入。如果它*不能*,那麼使用什麼舍入規則無關緊要;如果它不在中點,它們並不重要。 – Servy

+1

@ SamuelO'Malley採取點,編輯/擴大點添加此(並糾正我生鏽的C#語法)。 – pobrelkey

2

Math.Round()使用銀行家舍入算法。基本上它將任何以5結尾的數字向偶數進行舍入。所以1.565向下(朝向6),但向1.575朝上(朝向8)。如果添加許多舍入的數字,這可以避免積累的舍入誤差。