Is there a display formatter that will output decimals as these string representations in c# without doing any rounding?
// decimal -> string
20 -> 20
Another solution, based on dyslexicanaboko's answer, but independent of the current culture:
public static string ToTrimmedString(this decimal num)
{
string str = num.ToString();
string decimalSeparator = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
if (str.Contains(decimalSeparator))
{
str = str.TrimEnd('0');
if(str.EndsWith(decimalSeparator))
{
str = str.RemoveFromEnd(1);
}
}
return str;
}
public static string RemoveFromEnd(this string str, int characterCount)
{
return str.Remove(str.Length - characterCount, characterCount);
}
It's quite easy to do out of the box:
Decimal YourValue; //just as example
String YourString = YourValue.ToString().TrimEnd('0','.');
that will remove all trailing zeros from your Decimal.
The only thing that you need to do is add .ToString().TrimEnd('0','.');
to a decimal variable to convert a Decimal
into a String
without trailing zeros, like in the example above.
In some regions it should be a .ToString().TrimEnd('0',',');
(where they use a comma instead of a point, but you can also add a dot and a comma as parameters to be sure).
(you can also add both as parameters)
I made the below extension methods for myself to fit one of my projects, but maybe they'll be beneficial to someone else.
using System.Numerics;
using System.Text.RegularExpressions;
internal static class ExtensionMethod
{
internal static string TrimDecimal(this BigInteger obj) => obj.ToString().TrimDecimal();
internal static string TrimDecimal(this decimal obj) => new BigInteger(obj).ToString().TrimDecimal();
internal static string TrimDecimal(this double obj) => new BigInteger(obj).ToString().TrimDecimal();
internal static string TrimDecimal(this float obj) => new BigInteger(obj).ToString().TrimDecimal();
internal static string TrimDecimal(this string obj)
{
if (string.IsNullOrWhiteSpace(obj) || !Regex.IsMatch(obj, @"^(\d+([.]\d*)?|[.]\d*)$")) return string.Empty;
Regex regex = new Regex("^[0]*(?<pre>([0-9]+)?)(?<post>([.][0-9]*)?)$");
MatchEvaluator matchEvaluator = m => string.Concat(m.Groups["pre"].Length > 0 ? m.Groups["pre"].Value : "0", m.Groups["post"].Value.TrimEnd(new[] { '.', '0' }));
return regex.Replace(obj, matchEvaluator);
}
}
Though it will require a reference to System.Numerics
.
You can use the G0
format string if you are happy to accept scientific notation as per the documentation:
Fixed-point notation is used if the exponent that would result from expressing the number in scientific notation is greater than -5 and less than the precision specifier; otherwise, scientific notation is used.
You can use this format string as a parameter to the .ToString()
method, or by specifying it as a within an interpolated string. Both are shown below.
decimal input = 20.12500m;
Console.WriteLine(input.ToString("G0")); // outputs 20.125
Console.WriteLine($"{input:G0}"); // outputs 20.125
decimal fourDecimalPlaces = 0.0001m;
Console.WriteLine(fourDecimalPlaces.ToString("G0")); // outputs 0.0001
Console.WriteLine($"{fourDecimalPlaces:G0}"); // outputs 0.0001
decimal fiveDecimalPlaces = 0.00001m;
Console.WriteLine(fiveDecimalPlaces.ToString("G0")); // outputs 1E-05
Console.WriteLine($"{fiveDecimalPlaces:G0}"); // outputs 1E-05
I don't think it's possible out-of-the-box but a simple method like this should do it
public static string TrimDecimal(decimal value)
{
string result = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
if (result.IndexOf('.') == -1)
return result;
return result.TrimEnd('0', '.');
}
decimal val = 0.000000000100m;
string result = val == 0 ? "0" : val.ToString().TrimEnd('0').TrimEnd('.');