C# Convert string to double/decimal and back to string, keeping trailing zeroes, adding comas for thousands

谁说胖子不能爱 提交于 2019-12-23 09:48:12

问题


I am trying to get user input, parse it and then display with String.Format(), formatting thousands with comas.

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

Basically I want to keep all decimals(including trailing zeroes) that were provided and just add formatting for thousands. I tried:

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

回答1:


double.Parse(input) is a no go, as double does not keep track of the number of decimals.

decimal.Parse(input).ToString() will show that decimal does keep track of that. Unfortunately, decimal.Parse(input).ToString() uses this precision and doesn't use a thousands separator, and decimal.Parse(input).ToString("N") ignores the precision but does use a thousands separator.

Manually extracting the precision from the decimal works though, and that allows you to build the correct format string:

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);
}

This is based on the layout of decimal as described on MSDN:

Bits 16 to 23 must contain an exponent between 0 and 28, which indicates the power of 10 to divide the integer number.

See it working on .NET Fiddle. (courtesy of @Alisson)




回答2:


You can use regex for this:

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}";



回答3:


        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);
        }
    }

This splits the string at the decimal point and returns whatever is after the decimal point as was typed in BUT formats the integer part of the number with commas.




回答4:


If you don't mind 1000 converted to 1,000.00 then following is the best as it considers user's locale too.

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

If you want 1000 converted to just 1,000, then you can use the following:

string output2 = String.Format("{0:#,##0.##}", input);


来源:https://stackoverflow.com/questions/45333030/c-sharp-convert-string-to-double-decimal-and-back-to-string-keeping-trailing-ze

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!