C#的小数舍入提供了五种规则,常用的就是AwayFromZero和Toeven,这里主要介绍这两个枚举值,其他三个了解一下一般规则有印象就好,用的不多。
MidpointRounding枚举值
MidpointRounding枚举值相关含义:
枚举值 | 恰好在中间时的处理 | 一般规则 |
---|---|---|
ToEven | 向最近的偶数舍入 | 银行家舍入法 |
AwayFromZero | 向远离零方向舍入 | 更接近绝对值更大的整数(传统舍入) |
ToZero | 向零方向截断 | 去掉小数部分 |
ToNegativeInfinity | 向负无穷舍入 | 总是小于或等于原始值 |
ToPositiveInfinity | 向正无穷舍入 | 总是大于或等于原始值 |
具体差异:
-
传统舍入(MidpointRounding.AwayFromZero):无论是正数还是负数,遇到 .5 时,都会将结果舍入到更大的数字。例如,2.5 会四舍五入为 3,-2.5 会四舍五入为 -3。
-
银行家舍入(MidpointRounding.ToEven):当遇到 .5 时,结果会舍入到最接近的偶数。例如,2.5 会四舍五入为 2(最接近的偶数),而 3.5 会四舍五入为 4(最接近的偶数)。
测试代码如下:
using System;
using System.Diagnostics;
using System.IO;
class Program
{
static void Main()
{
// 一些测试数字,保留三位小数
double[] numbers = {
1.2354,
1.2454,
1.2515,
1.2625,
1.2765,
1.2875,
1.2886,
1.2896};
Console.WriteLine("传统舍入(AwayFromZero):");
foreach (var num in numbers)
{
Console.WriteLine($"{num} => {Math.Round(num, 3, MidpointRounding.AwayFromZero)}");
}
Console.WriteLine("\n银行家舍入(ToEven):");
foreach (var num in numbers)
{
Console.WriteLine($"{num} => {Math.Round(num, 3, MidpointRounding.ToEven)}");
}
Console.ReadKey();
}
}
结果如下:
对比两个方法的差异就是银行家四舍五入会在第四位小数是5,看第三位是奇数还是偶数,如果是奇数则入到下一个偶数,如果是偶数则不变。
注意:
在C#中,Math.Round(double value, int digits)
函数默认使用的是银行家四舍五入,这个时候如果用C#的四舍五入的方法和Windows的计算器计算出来的结果会不一样,类似于1.2625
这个保留三位小数C#默认采用银行家四舍五入等于1.262
,然而计算机采用传统四舍五入等于1.263
。开发使用银行家四舍五入,测试使用传统四舍五入,这个时候就会出现"Bug",为了统一使用传统四舍五入,可以使用函数Math.Round(1.2625, 3, MidpointRounding.AwayFromZero);
,参数mode
赋值MidpointRounding.AwayFromZero
。