Reputation: 12944
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.
Upvotes: 13
Views: 24997
Reputation: 34967
The method below (š¦) deals with the following edge cases:
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;
}
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
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");
}
Upvotes: 0
Reputation: 2873
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.
Upvotes: 16
Reputation: 4542
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');
Upvotes: 0