如何实现小数点后第三位为5时截断的金额保留两位小数需求
金额自定义保留两位小数问题解答
问题原因
- 你的需求属于自定义舍入规则,和C#内置的两种舍入模式都不匹配:
AwayFromZero模式为标准四舍五入,小数点后第三位≥5就会向前进1,你的规则要求仅第三位>5时才进位,等于5时直接舍去,不符合该模式逻辑ToEven(银行家舍入)模式会根据前一位的奇偶性判断5是否进位,同样和你的需求不匹配
- 浮点数精度问题也可能导致结果偏差:
double类型的1099948.275在内存中存储时可能存在微小的精度误差,实际存储值略大于理论值,也会导致Math.Round的结果不符合预期,金额计算场景优先推荐使用decimal类型避免该类问题。
实现方案
你提到的先判断小数点后第三位数值的方案完全可行,基于decimal类型的实现代码如下:
public static decimal CustomMoneyRound(decimal input) { // 放大1000倍后取整,获取到小数点后三位对应的整数 decimal scaledValue = input * 1000; long integerScaled = (long)Math.Truncate(scaledValue); // 取第三位小数的数值 int thirdDecimalDigit = (int)(integerScaled % 10); if (thirdDecimalDigit > 5) { // 第三位大于5,向第二位进1后取两位小数 return Math.Truncate(scaledValue / 10 + 1) / 100; } else { // 第三位小于等于5,直接截断保留两位小数 return Math.Truncate(scaledValue / 10) / 100; } }
调用测试结果和你的要求完全匹配:
CustomMoneyRound(1099948.275m)输出1099948.27CustomMoneyRound(1099948.276m)输出1099948.28CustomMoneyRound(1099948.274m)输出1099948.27
内容的提问来源于stack exchange,提问作者Tronics
相关产品推荐
相关产品推荐

