显示小数而不带尾随零的最佳方法

时间:2010-06-23 18:54:58

标签: c# formatting decimal

是否有显示格式化程序在c#中输出小数作为这些字符串表示而不进行任何舍入?

// decimal -> string

20 -> 20
20.00 -> 20
20.5 -> 20.5
20.5000 -> 20.5
20.125 -> 20.125
20.12500 -> 20.125
0.000 -> 0

{0.#}将会舍入,并且使用某些修剪类型函数将无法使用网格中的绑定数字列。

14 个答案:

答案 0 :(得分:130)

您是否需要显示最大小数位数? (您的示例最多为5个。)

如果是这样,我认为用“0。#####”格式化可以达到你想要的效果。

    static void Main(string[] args)
    {
        var dList = new decimal[] { 20, 20.00m, 20.5m, 20.5000m, 20.125m, 20.12500m, 0.000m };

        foreach (var d in dList)
            Console.WriteLine(d.ToString("0.#####"));
    }

答案 1 :(得分:29)

我刚学会了如何正确使用G格式说明符。请参阅MSDN Documentation。有一点注意说明当没有指定精度时,将为十进制类型保留尾随零。为什么他们会这样做我不知道,但指定我们的精度的最大位数应解决这个问题。因此,为了格式化小数,G29是最好的选择。

decimal test = 20.5000m;
test.ToString("G"); // outputs 20.5000 like the documentation says it should
test.ToString("G29"); // outputs 20.5 which is exactly what we want

答案 2 :(得分:14)

这种字符串格式应该是你的日子:“0。#############################”。请记住,小数最多可以包含29位有效数字。

示例:

? (1000000.00000000000050000000000m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.00000000000050000000001m).ToString("0.#############################")
-> 1000000.0000000000005

? (1000000.0000000000005000000001m).ToString("0.#############################")
-> 1000000.0000000000005000000001

? (9223372036854775807.0000000001m).ToString("0.#############################")
-> 9223372036854775807

? (9223372036854775807.000000001m).ToString("0.#############################")
-> 9223372036854775807.000000001

答案 3 :(得分:9)

这是我在上面看到的另一种变化。在我的情况下,我需要保留小数点右侧的所有有效数字,意味着在最高有效数字后丢弃全零。只是觉得分享会很好。我不能保证这个效率,但是当试图达到美学时,你已经非常被低效率所困扰。

public static string ToTrimmedString(this decimal target)
{
    string strValue = target.ToString(); //Get the stock string

    //If there is a decimal point present
    if (strValue.Contains("."))
    {
        //Remove all trailing zeros
        strValue = strValue.TrimEnd('0');

        //If all we are left with is a decimal point
        if (strValue.EndsWith(".")) //then remove it
            strValue = strValue.TrimEnd('.');
    }

    return strValue;
}

这就是全部,只是想投入我的两分钱。

答案 4 :(得分:4)

扩展方法:

public static class Extensions
{
    public static string TrimDouble(this string temp)
    {
        var value = temp.IndexOf('.') == -1 ? temp : temp.TrimEnd('.', '0');
        return value == string.Empty ? "0" : value;
    }
}

示例代码:

double[] dvalues = {20, 20.00, 20.5, 20.5000, 20.125, 20.125000, 0.000};
foreach (var value in dvalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.ToString().TrimDouble()));

Console.WriteLine("==================");

string[] svalues = {"20", "20.00", "20.5", "20.5000", "20.125", "20.125000", "0.000"};
foreach (var value in svalues)
    Console.WriteLine(string.Format("{0} --> {1}", value, value.TrimDouble()));

输出:

20 --> 20
20 --> 20
20,5 --> 20,5
20,5 --> 20,5
20,125 --> 20,125
20,125 --> 20,125
0 --> 0
==================
20 --> 20
20.00 --> 2
20.5 --> 20.5
20.5000 --> 20.5
20.125 --> 20.125
20.125000 --> 20.125
0.000 --> 0

答案 5 :(得分:3)

另一种解决方案,基于dyslexicanaboko's答案,但与当前文化无关:

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

答案 6 :(得分:2)

开箱即用很容易:

Decimal YourValue; //just as example   
String YourString = YourValue.ToString().TrimEnd('0','.');

将从十进制中删除所有尾随零。

您唯一需要做的就是将.ToString().TrimEnd('0','.');添加到十进制变量,将Decimal转换为String而不会尾随零,如上例所示。

在某些地区,它应该是.ToString().TrimEnd('0',',');(他们使用逗号代替点,但您也可以添加点和逗号作为参数来确定)。

(您也可以将两者都添加为参数)

答案 7 :(得分:1)

我认为这不可能是开箱即用的,但这样的简单方法应该这样做

public static string TrimDecimal(decimal value)
{
    string result = value.ToString(System.Globalization.CultureInfo.InvariantCulture);
    if (result.IndexOf('.') == -1)
        return result;

    return result.TrimEnd('0', '.');
}

答案 8 :(得分:0)

decimal val = 0.000000000100m;
string result = val == 0 ? "0" : val.ToString().TrimEnd('0').TrimEnd('.');

答案 9 :(得分:0)

我最终得到了以下代码:

    public static string DropTrailingZeros(string test)
    {
        if (test.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
        {
            test = test.TrimEnd('0');
        }

        if (test.EndsWith(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator))
        {
            test = test.Substring(0,
                test.Length - CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator.Length);
        }

        return test;
    }

答案 10 :(得分:0)

我最终遇到了这个变体:

public static string Decimal2StringCompact(decimal value, int maxDigits)
    {
        if (maxDigits < 0) maxDigits = 0;
        else if (maxDigits > 28) maxDigits = 28;
        return Math.Round(value, maxDigits, MidpointRounding.ToEven).ToString("0.############################", CultureInfo.InvariantCulture);
    }

优势:

您可以指定要在运行时显示的点之后的最大有效位数;

您可以显式指定舍入方法;

您可以显式控制文化。

答案 11 :(得分:0)

您可以创建扩展方法

public static class ExtensionMethod {
  public static decimal simplify_decimal(this decimal value) => decimal.Parse($"{this:0.############}");
}

答案 12 :(得分:0)

我为自己设计了以下扩展方法以适合我的一个项目,但也许对其他人会有所帮助。

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

尽管它需要引用System.Numerics

答案 13 :(得分:0)

如果您愿意接受the documentation的科学符号,则可以使用G0格式的字符串:

如果用科学计数法表示数字所产生的指数大于-5且小于精度说明符,则使用定点计数法;否则,将使用科学计数法。

您可以将此格式字符串用作.ToString()方法的参数,也可以将其指定为within an interpolated string。两者都显示如下。

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