简体   繁体   中英

How to format a decimal without trailing zeros

I've just learned that a decimal somehow remembers how much trailaing zero's were needed to store a number. With other words: it remembers the size of the fraction.

For example:

123M.ToString() ==> resuls in: 123
123.00M.ToString() ==> resuls in: 123.00
123.450M.ToString() ==> resuls in: 123.450

I am looking for a formatting string or another trick to get rid of those "unneeded" trailing zeros, but keeping the significant digits. So:

123M.ToString() ==> resuls in: 123
123.00M.ToString() ==> resuls in: 123
123.450M.ToString() ==> resuls in: 123.45

Removing the zeros at the end of the new string is not a real option for me, because then I have to find out if the string contains a fraction and if so, also have to remove the optional '.' or ',' depending on the culture, etc.

There are several ways to do it, but since you are converting to a String object anyway, I suppose you could try something like this:

myDecimalVariable.ToString("G29");

or, using your code above, assuming 123.00M is your decimal:

123.00M.ToString("G29");

Here is the explanation of how that concise example works:

The G format with a number means to format that many significant digits. Because 29 is the most significant digits that a Decimal can have, this will effectively truncate the trailing zeros without rounding.

just apply the Format specifier zero and will remove the trailing zeros:

string test = (1.23M * 100M).ToString("0");
//prints 123.
string test2 = 123.450M.ToString(".00");
//prints 123.45.
string test3 = 123.450M.ToString().Trim('0');

The method below (🦍) deals with the following edge cases:

  • Input: 123.00M, expecting "123.00"
    • ❌ G29: 123
    • ✅ 🦍: 123.00
  • Input: -0.00000000001M, expecting "-0.00000000001"
    • ❌ G29: -1E-11
    • ✅ 🦍: -0.00000000001
private static string SlowButStrong(decimal v)
{
  if( v % 1 == 0) return v.ToString(); // If no decimal digits, let's leave it alone
  var withNoZeroes = v.ToString().TrimEnd('0');
  return withNoZeroes.EndsWith('.') ? withNoZeroes + "00" : withNoZeroes;
}

Test output

Input 123M, expecting 123
✅ G29: 123
✅ 🦍: 123
✅ ⛵: 123

Input 123.00M, expecting 123.00
❌ G29: 123
✅ 🦍: 123.00
❌ ⛵: 123

Input 123.45M, expecting 123.45
✅ G29: 123.45
✅ 🦍: 123.45
✅ ⛵: 123.45

Input 123.450M, expecting 123.45
✅ G29: 123.45
✅ 🦍: 123.45
✅ ⛵: 123.45

Input 5.00000001M, expecting 5.00000001
✅ G29: 5.00000001
✅ 🦍: 5.00000001
✅ ⛵: 5.00000001

Input -0.00000000001M, expecting -0.00000000001
❌ G29: -1E-11
✅ 🦍: -0.00000000001
✅ ⛵: -0.00000000001

Input 10000000000000000000000M, expecting 10000000000000000000000
✅ G29: 10000000000000000000000
✅ 🦍: 10000000000000000000000
✅ ⛵: 10000000000000000000000

Arbitrary test case

public static void Main(string[] args)
{
    Test("123M", 123M, "123");
    Test("123.00M", 123.00M, "123.00");
    Test("123.45M", 123.45M, "123.45");
    Test("123.450M", 123.450M, "123.45");
    Test("5.00000001M", 5.00000001M, "5.00000001");
    Test("-0.00000000001M", -0.00000000001M, "-0.00000000001");
    Test("10000000000000000000000M", 10000000000000000000000M, "10000000000000000000000");
}

private static void Test(string vs, decimal v, string expected)
{
    Console.OutputEncoding = System.Text.Encoding.UTF8;

    Console.WriteLine($"Input {vs}, expecting {expected}");
    Print("G29", v.ToString("G29"), expected);
    Print("🦍", SlowButStrong(v), expected);
    Print("⛵", LessSlowButStrong(v), expected);
    Console.WriteLine();
}

private static void Print(string prefix, string formatted, string original)
{
    var mark = formatted == original ? "✅" : "❌"; 
    Console.WriteLine($"{mark} {prefix:10}: {formatted}");
}

private static string SlowButStrong(decimal v)
{
    if( v % 1 == 0) return v.ToString(); // If no decimal digits, let's leave it alone
    var withNoZeroes = v.ToString().TrimEnd('0');
    return withNoZeroes.EndsWith('.') ? withNoZeroes + "00" : withNoZeroes;
}

private static string LessSlowButStrong(decimal v)
{
    return v.ToString((v < 1) ? "" : "G29");
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM