Math.Round()
色即是空,空即是色。
C#中的Math.Round()并不是使用的"四舍五入"法。其实在VB、VBScript、C#、J#、T-SQL中Round函数都是采用Banker’s rounding(银行家算法),即:四舍六入五取偶。事实上这也是IEEE的规范,因此所有符合IEEE标准的语言都应该采用这样的算法。如:
Math.Round(0.4) //result:0
Math.Round(0.6) //result:1
Math.Round(0.5) //result:0
Math.Round(1.5) //result:2
Math.Round(2.5) //result:2
Math.Round(3.5) //result:4
Math.Round(4.5) //result:4
Math.Round(5.5) //result:6
Math.Round(6.5) //result:6
Math.Round(7.5) //result:8
Math.Round(8.5) //result:8
Math.Round(9.5) //result:10
中国式四舍五入
千呼万唤始出来,犹抱琵琶半遮面。
.NET 2.0 开始,Math.Round 方法提供了一个枚举选项 MidpointRounding.AwayFromZero 可以用来实现传统意义上的"四舍五入"。即: Math.Round(4.5, MidpointRounding.AwayFromZero) = 5。
Math.Round(0.4, MidpointRounding.AwayFromZero); // result:0
Math.Round(0.6, MidpointRounding.AwayFromZero); // result:1
Math.Round(0.5, MidpointRounding.AwayFromZero); // result:1
Math.Round(1.5, MidpointRounding.AwayFromZero); // result:2
Math.Round(2.5, MidpointRounding.AwayFromZero); // result:3
Math.Round(3.5, MidpointRounding.AwayFromZero); // result:4
Math.Round(4.5, MidpointRounding.AwayFromZero); // result:5
总结
原始归一。
如果用这个计算小数的话,就不灵了!!!
必须用第七个重载方法,decimal Round(decimal d, int decimals, MidpointRounding mode),这样计算出来的小数才是真正的中国式四舍五入!!
Math.Round(526.925, 2)
526.92
Math.Round(526.925, 2,MidpointRounding.AwayFromZero)
526.92
Math.Round((decimal)526.925, 2)
526.92
Math.Round((decimal)526.925, 2,MidpointRounding.AwayFromZero)
526.93
直接上干货,举个栗子!!
#region RoundMode
public enum RoundMode
{
/// <summary>
/// 四舍五入
/// </summary>
AwayFromZero,
/// <summary>
/// 设置为四舍六入五取偶
/// </summary>
ToEven,
/// <summary>
/// 按精度进位
/// </summary>
Carry,
/// <summary>
/// 按精度舍尾
/// </summary>
Truncation,
}
#endregion
#region 将金额格式化
/// <summary>
/// 将金额格式化
/// </summary>
/// <param name="d"></param>
/// <returns></returns>
public static decimal FormatDecimal(this object d)
{
var result = 0m;
if (!d.IsNullOrEmptyOrWhiteSpace())
{
result = Convert.ToDecimal(d);
result = Round(result, 2, RoundMode.AwayFromZero);
}
return result;
}
/// <summary>
/// 十进制四舍五入
/// </summary>
public static decimal Round(decimal value, int decimals = 0, RoundMode mode = RoundMode.AwayFromZero)
{
if (mode == RoundMode.AwayFromZero || mode == RoundMode.ToEven)
{
MidpointRounding mpMode = MidpointRounding.AwayFromZero;
if (mode == RoundMode.ToEven)
mpMode = MidpointRounding.ToEven;
return Math.Round(value, decimals, mpMode);
}
else
{
decimal scale = Convert.ToDecimal(Math.Pow(10, decimals));
decimal newValue = value * scale;
if (mode == RoundMode.Carry)
newValue = Math.Ceiling(newValue);
else
newValue = Math.Truncate(newValue);
return newValue / scale;
}
}
#endregion