.NET中Decimal默认舍入模式与货币格式化行为差异问询
.NET中货币格式化与decimal.Round舍入结果差异的原因
先看示例代码及输出:
decimal value = 12.345m; Console.WriteLine(value.ToString("C"));
£12.35
再看参考代码及输出:
Console.WriteLine(decimal.Round(value, 2));
12.34
已知.NET中默认MidpointRounding模式为MidpointRounding.ToEven,为何此值格式化为货币时会向上舍入得到12.35,而非偶数位的12.34?
核心原因是货币格式化的舍入逻辑和decimal.Round的默认逻辑并不相同:
decimal.Round(value, 2)直接采用默认的MidpointRounding.ToEven(银行家舍入规则),对于12.345这种恰好处于中间的数值,会观察保留位的前一位(也就是百分位的4,属于偶数),因此最终舍入结果为12.34。- 而
ToString("C")执行货币格式化时,会遵循当前区域设置对应的货币舍入规则,并非直接套用MidpointRounding.ToEven。以英镑对应的区域设置为例,其默认货币舍入规则是四舍五入(对应MidpointRounding.AwayFromZero),所以12.345会被向上舍入为12.35。
如果需要让货币格式化也使用银行家舍入,可以自定义NumberFormatInfo来指定规则,示例代码如下:
decimal value = 12.345m; var nfi = new NumberFormatInfo { CurrencySymbol = "£", MidpointRounding = MidpointRounding.ToEven }; Console.WriteLine(value.ToString("C", nfi));
此时输出结果为:
£12.34
内容的提问来源于stack exchange,提问作者Matthew Layton
相关产品推荐
相关产品推荐

