如何将49.999999999999993截断为49.99且不四舍五入?
截断浮点数到指定小数位且不四舍五入的方法
针对你遇到的49.999999999999993这类接近整数的double值,以下是几种比固定长度字符串截取更可靠的截断方法:
方法1:数学运算截断(正数场景)
利用Math.Floor向下取整的特性,先将数值放大对应倍数(保留两位小数则乘100),取整后再缩小回原比例:
double number = 49.999999999999993; double truncated = Math.Floor(number * 100) / 100; string result = truncated.ToString("0.00"); // 输出 "49.99"
注意:如果需要处理负数,需替换为Math.Ceiling,避免出现-49.999截断成-50.00的问题
方法2:借助Decimal类型提升精度
Decimal类型的十进制精度更高,能更准确地表示目标数值,再进行截断操作:
double number = 49.999999999999993; decimal decimalNum = (decimal)number; decimal truncated = decimal.Floor(decimalNum * 100) / 100; string result = truncated.ToString("0.00"); // 输出 "49.99"
这种方法受浮点精度影响更小,可靠性更强。
方法3:更通用的字符串截取逻辑
避免固定长度Substring的局限性,根据小数点位置动态截取:
double number = 49.999999999999993; string numStr = number.ToString(); int dotPos = numStr.IndexOf('.'); string result = dotPos != -1 ? numStr.Substring(0, Math.Min(dotPos + 3, numStr.Length)) : $"{numStr}.00"; // 输出 "49.99"
此方法能适配不同位数的整数部分,比如1234.567会被截断为1234.56,789会补为789.00。
为什么之前的方法失效?
因为double是二进制浮点数,49.999999999999993的二进制表示实际上非常接近50,导致格式化和Math.Round都因精度误差触发了向上取整。
内容的提问来源于stack exchange,提问作者Ahmad
相关产品推荐
相关产品推荐

