C#将字符串转换为双精度/小数,再转换回字符串,保留尾随零,并添加千位分隔符

5

我正在尝试获取用户输入,解析并使用String.Format()显示,使用逗号格式化千位分隔符。

So, if user provides
1000  I will display 1,000
1000.00 => 1,000.00
1000.0  => 1,000.0
1,000.5 => 1,000.5

基本上,我想保留提供的所有小数(包括尾随的零)并只添加千位分隔符格式。我尝试过:

String.Format("{0:#,0.######}" , Decimal.Parse(input));
String.Format("{0:#,0.######}" , Double.Parse(input);
4个回答

7

double.Parse(input) 不可行,因为 double 类型不能精确地追踪小数位数。

decimal.Parse(input).ToString() 可以显示 decimal 类型的小数位数。不过, decimal.Parse(input).ToString() 使用了这个小数位数,但没有使用千分位分隔符,而 decimal.Parse(input).ToString("N") 忽略了小数位数,但使用了千分位分隔符。

不过,手动从 decimal 类型中提取小数位数是可行的,这样就可以建立正确的格式字符串:

static string InsertThousandsSeparator(string input) {
    var dec = decimal.Parse(input);
    var bits = decimal.GetBits(dec);
    var prec = bits[3] >> 16 & 255;
    return dec.ToString("N" + prec);
}

这是基于MSDN中描述的decimal布局:(链接) 引用如下:
位16到23必须包含介于0和28之间的指数,该指数表示将整数除以10的幂次方。
在.NET Fiddle上查看其工作情况:(链接)(由@Alisson提供)。

没错,所有测试用例都通过了(我亲自测试过)。非常干净利落的解决方案。 - Alisson Reinaldo Silva
太好了,非常感谢。我本来想写一些正则表达式的,但我真的很想避免这样做。 - Razkar

0
你可以使用正则表达式来实现这个功能:
var input = "1000.50000";
var regex = new Regex("^(?<int>-?[\\d,]+)\\.(?<fract>\\d+)$");
var match = regex.Match(input);
var integralPart = match.Groups["int"].Value.Replace(",", "");
var fractionalPart = match.Groups["fract"].Value;
var result = $"{decimal.Parse(integralPart):n0}.{fractionalPart}";

0
        public string DoFormat(string num)
    {
        int pt = num.IndexOf(".");
        if (pt > 0)
        {
            return string.Format("{0:#,##0}", num.Substring(0, pt)) + num.Substring(pt, num.Length - pt);
        }
        else
        {
            return string.Format("{0:#,##0}", num);
        }
    }

这将字符串在小数点处分割,并将小数点后面的内容作为原样返回,但会使用逗号格式化数字的整数部分。


-1

如果您不介意将1000转换为1,000.00,那么以下是最好的选择,因为它也考虑了用户的语言环境。

string output = String.Format("{0:n}", input);

如果你想将1000转换为1,000,那么可以使用以下代码:
string output2 = String.Format("{0:#,##0.##}", input);

如果您不介意将1000转换为1,000.00。请注意,问题中涵盖了这一点,如果您忽略问题中的内容,任何答案都可以。 - user743382
这不是 OP 所要求的。他们想保留相同数量的小数位。 - Alisson Reinaldo Silva
同意,没有仔细阅读问题就回答不好。我的错。 - Sach

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接