C# 中沒有四捨五入函數,程序語言都沒有四捨五入函數,因為四捨五入算法不科學,國際通行的是 Banker 舍入法
Bankers rounding(銀行家舍入)算法,即四捨六入五取偶。事實上這也是 IEEE 規定的舍入標準。因此所有符合 IEEE 標準的語言都應該是採用這一算法的
Math.Round 方法默認的也是 Banker 舍入法
在 .NET 2.0 中 Math.Round 方法有幾個重載方法
Math.Round(Decimal, MidpointRounding)
Math.Round(Double, MidpointRounding)
Math.Round(Decimal, Int32, MidpointRounding)
Math.Round(Double, Int32, MidpointRounding)
將小數值舍入到指定精度。MidpointRounding 參數,指定當一個值正好處於另兩個數中間時如何舍入這個值
該參數是個 MidpointRounding 枚舉
此枚舉有兩個成員,MSDN 中的説明是:
AwayFromZero 當一個數字是其他兩個數字的中間值時,會將其舍入為兩個值中絕對值較小的值。
ToEven 當一個數字是其他兩個數字的中間值時,會將其舍入為最接近的偶數。
注 意!這裏關於 MidpointRounding.AwayFromZero 的説明是錯誤的!實際舍入為兩個值中絕對值較大的值。不過 MSDN 中的 例子是正確的,英文描述原文是 it is rounded toward the nearest number that is away from zero.
所以,要實現四捨五入函數,對於正數,可以加一個 MidpointRounding.AwayFromZero 參數指定當一個數字是其他兩個數字的中間值時其舍入為兩個值中絕對值較大的值,例:
Math.Round(3.45, 2, MidpointRounding.AwayFromZero)
不過對於負數上面的方法就又不對了
因此需要自己寫個函數來處理
第一個函數:
double Round(double value, int decimals)
{
if (value < 0)
{
return Math.Round(value + 5 / Math.Pow(10, decimals + 1), decimals, MidpointRounding.AwayFromZero);
}
else
{
return Math.Round(value, decimals, MidpointRounding.AwayFromZero);
}
}
第二個函數:
double Round(double d, int i)
{
if(d >=0)
{
d += 5 * Math.Pow(10, -(i + 1));
}
else
{
d += -5 * Math.Pow(10, -(i + 1));
}
string str = d.ToString();
string[] strs = str.Split('.');
int idot = str.IndexOf('.');
string prestr = strs[0];
string poststr = strs[1];
if(poststr.Length > i)
{
poststr = str.Substring(idot + 1, i);
}
string strd = prestr + "." + poststr;
d = Double.Parse(strd);
return d;
}
參數:d表示要四捨五入的數;i表示要保留的小數點後為數。
其中第二種方法是正負數都四捨五入,第一種方法是正數四捨五入,負數是五舍六入。
備註:個人認為第一種方法適合處理貨幣計算,而第二種方法適合數據統計的顯示。