在C#中如何将double类型值向上/向下舍入至比输入少一位小数位?
解决方案
问题核心是自动识别输入数值的小数位数,再基于此计算舍入精度。由于double的二进制浮点数特性可能导致十进制小数精度丢失,建议先通过字符串解析获取准确的小数位数,再结合数学方法完成舍入。
实现思路
- 解析输入数值的字符串表示,拆分整数与小数部分,获取实际小数位数;
- 计算目标舍入精度:
小数位数 - 1; - 用
Math.Floor(向下舍入)或Math.Ceiling(向上舍入)结合缩放完成计算,优先推荐decimal类型避免浮点数误差。
代码实现
方式1:基于字符串解析 + double运算
public double RoundDownAuto(double number) { // 去除末尾无效的0和小数点,还原真实小数位数 string numStr = number.ToString().TrimEnd('0').TrimEnd('.'); int decimalPlaces = numStr.Contains('.') ? numStr.Split('.')[1].Length : 0; if (decimalPlaces <= 0) return number; // 整数无需舍入 int targetPlaces = decimalPlaces - 1; double scale = Math.Pow(10, targetPlaces); // 修正double精度误差导致的Floor计算偏差 return Math.Floor((number + 1e-12) * scale) / scale; } public double RoundUpAuto(double number) { string numStr = number.ToString().TrimEnd('0').TrimEnd('.'); int decimalPlaces = numStr.Contains('.') ? numStr.Split('.')[1].Length : 0; if (decimalPlaces <= 0) return number; int targetPlaces = decimalPlaces - 1; double scale = Math.Pow(10, targetPlaces); // 修正double精度误差导致的Ceiling计算偏差 return Math.Ceiling((number - 1e-12) * scale) / scale; }
方式2:使用decimal类型(更精确)
decimal专门用于十进制精确计算,能避免double的精度丢失问题,适合处理货币、高精度小数场景:
public decimal RoundDownAuto(decimal number) { string numStr = number.ToString().TrimEnd('0').TrimEnd('.'); int decimalPlaces = numStr.Contains('.') ? numStr.Split('.')[1].Length : 0; if (decimalPlaces <= 0) return number; int targetPlaces = decimalPlaces - 1; decimal scale = (decimal)Math.Pow(10, targetPlaces); return Math.Floor(number * scale) / scale; } public decimal RoundUpAuto(decimal number) { string numStr = number.ToString().TrimEnd('0').TrimEnd('.'); int decimalPlaces = numStr.Contains('.') ? numStr.Split('.')[1].Length : 0; if (decimalPlaces <= 0) return number; int targetPlaces = decimalPlaces - 1; decimal scale = (decimal)Math.Pow(10, targetPlaces); return Math.Ceiling(number * scale) / scale; }
测试验证
- 输入
100.67:RoundDownAuto(100.67)→100.6RoundUpAuto(100.67)→100.7
- 输入
50.563:RoundDownAuto(50.563)→50.56RoundUpAuto(50.563)→50.57
- 输入
20.1(一位小数):RoundDownAuto(20.1)→20RoundUpAuto(20.1)→20
注意事项
- 若输入为科学计数法格式(如
1.23e-4),需先转换为普通十进制字符串再解析; double类型仅在非高精度场景下使用,涉及精确计算优先选decimal。
内容的提问来源于stack exchange,提问作者zedge08
相关产品推荐
相关产品推荐

