C#中如何将decimal按指定格式转字符串且转换时不四舍五入
C# decimal转字符串:不四舍五入保留指定位数+自定义分隔符
核心需求
实现decimal类型转字符串逻辑,满足两个要求:
- 转换过程不触发四舍五入,小数部分直接截断到指定位数
- 支持自定义千位分隔符、小数分隔符的格式规则
给定测试条件
测试数值:
var price = 4569.996M;
自定义区域性格式配置:
customCulture.NumberFormat.NumberDecimalSeparator = ","; customCulture.NumberFormat.NumberGroupSeparator = ".";
期望输出:result = "4.569,99"
原有方案问题
之前尝试的代码均不满足要求,问题点如下:
var result = price.ToString("#,##0.##", CustomCulture); // 输出"4.570",触发默认四舍五入逻辑 var result = Convert.ToDecimal(price).ToString("#,#.#########", customCulture); // 输出"4.569,996",未截断到2位小数 var result = price.ToString("N"); // 输出"4,570.00",分隔符不符合配置+触发四舍五入 var result = price.ToString("N", customCulture); // 输出"4.569,996",未截断到2位小数
正确实现方案
.NET内置的数字格式化方法默认会对超出指定位数的小数做四舍五入,因此必须先对原始值做截断处理,再执行格式化操作。
实现代码
using System.Globalization; // 初始化自定义区域配置 var customCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone(); customCulture.NumberFormat.NumberDecimalSeparator = ","; customCulture.NumberFormat.NumberGroupSeparator = "."; // 原始值与配置项 var price = 4569.996M; int keepDecimalLength = 2; // 需要保留的小数位数 // 第一步:截断小数位,全程不做四舍五入 decimal scale = (decimal)Math.Pow(10, keepDecimalLength); // 为避免double转decimal的精度误差,固定保留2位时可直接写 decimal scale = 100m; decimal truncatedValue = Math.Truncate(price * scale) / scale; // 第二步:按自定义格式输出 var result = truncatedValue.ToString($"N{keepDecimalLength}", customCulture); // 输出结果:4.569,99,完全符合预期
逻辑说明
Math.Truncate方法仅取数值的整数部分,不会做任何进位处理,乘/除倍率的操作可以精准将小数位截断到指定长度,从根源上避免四舍五入- 截断完成后再使用标准
N格式符搭配自定义区域信息输出,会自动按配置添加千位分隔符、补全对应位数的小数 - 该逻辑兼容任意decimal输入值,仅需要修改
keepDecimalLength参数即可适配不同小数保留位数的需求
注意:禁止直接对原始值调用ToString方法指定小数位,否则.NET内置格式化逻辑会自动执行四舍五入,无法得到截断结果。
内容的提问来源于stack exchange,提问作者mth12
相关产品推荐
相关产品推荐

