Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/339.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 显示不带尾随零的小数的最佳方法_C#_Formatting_Decimal - Fatal编程技术网

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

C# 显示不带尾随零的小数的最佳方法,c#,formatting,decimal,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.#}将进行四舍五入,并且使用某些修剪类型函数无法处理网格中的绑定数字列。是否有需要显示的最大小数位数?(您的示例最多有5个) 如

是否有一个显示格式化程序可以输出小数作为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.#}将进行四舍五入,并且使用某些修剪类型函数无法处理网格中的绑定数字列。

是否有需要显示的最大小数位数?(您的示例最多有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.#####"));
    }
扩展方法:

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

我认为这不可能开箱即用,但像这样一个简单的方法应该可以做到

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 YourValue; //just as example   
String YourString = YourValue.ToString().TrimEnd('0','.');
这将从小数中删除所有尾随的零

您只需要添加
.ToString().TrimEnd('0',')
转换为十进制变量,将
十进制
转换为不带尾随零的
字符串
,如上例所示

在某些区域,它应该是
.ToString().TrimEnd('0',',')(其中使用逗号而不是点,但也可以添加点和逗号作为参数)


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

此字符串格式应该适合您的一天:“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

我刚刚学习了如何正确使用
G
格式说明符。看。下面有一条注释指出,当未指定精度时,十进制类型将保留尾随零。我不知道他们为什么会这样做,但为我们的精度指定最大位数应该可以解决这个问题。因此,对于格式化小数,
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

这是我在上面看到的另一个变化。在我的例子中,我需要保留小数点右侧的所有有效数字,这意味着在最有效的数字之后删除所有零。我只是想和大家分享一下。虽然我不能保证这样做的有效性,但当你试图达到美学效果时,你已经被诅咒为效率低下

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

仅此而已,我只想投入我的两分钱。

另一个解决方案,基于答案,但与当前文化无关:

decimal val = 0.000000000100m;
string result = val == 0 ? "0" : val.ToString().TrimEnd('0').TrimEnd('.');
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);
}

我最终得到了以下代码:

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

我最终得到了这个变体:

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);
    }
公共静态字符串小数2stringcompact(十进制值,int-maxDigits)
{
如果(maxDigits<0)maxDigits=0;
如果(maxDigits>28)maxDigits=28,则为else;
返回Math.Round(value,maxDigits,middpointrounding.ToEven).ToString(“0.”、0.”、0;
}
优点:

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

可以显式指定一个round方法


您可以显式控制区域性。

您可以创建扩展方法

public static class ExtensionMethod {
  public static decimal simplify_decimal(this decimal value) => decimal.Parse($"{this: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.Text.RegularExpressions;
内部静态类扩展方法
{
内部静态字符串TrimDecimal(此BigInteger obj)=>obj.ToString().TrimDecimal();
内部静态字符串TrimDecimal(此十进制obj)=>new BigInteger(obj).ToString().TrimDecimal();
内部静态字符串TrimDecimal(此双obj)=>new BigInteger(obj).ToString().TrimDecimal();
内部静态字符串TrimDecimal(此浮点obj)=>new BigInteger(obj).ToString().TrimDecimal();
内部静态字符串TrimDecimal(此字符串obj)
{
if(string.IsNullOrWhiteSpace(obj)| |!Regex.IsMatch(obj,@“^(\d+([.]\d*)?|[.]\d*)$”)返回string.Empty;
正则表达式正则表达式=新正则表达式(“^[0]*(?([0-9]+))(?([.][0-9]*)?)$”;
MatchEvaluator MatchEvaluator=m=>string.Concat(m.Groups[“pre”].Length>0?m.Groups[“pre”].Value:“0”,m.Groups[“post”].Value.TrimEnd(新[]{.',“0”}));
返回regex.Replace(对象、匹配计算器);
}
}

尽管它需要参考
System.Numerics

如果您愿意接受科学符号,您可以使用
G0
格式字符串,具体如下:

如果在科学记数法中表示数字的指数大于-5且小于精度说明符,则使用定点记数法;否则,使用科学符号

您可以将此格式字符串用作
.ToString()
方法的参数,或将其指定为一个参数。两者都显示在下面

十进制输入=20.12500m;
Console.WriteLine(input.ToString(“G0”);//产出20.125
Console.WriteLine($“{input:G0}”);//产出20.125
小数点后四位小数=0.0001m;
Console.WriteLine(四个十进制位置的ToString(“G0”);//产出0.0001
Console.WriteLine($“{fourDecimalPlaces:G0}”);//产出0.0001
小数点五位数=0.00001m;
Console.WriteLine(五个指定位置的ToString(“G0”);//产出1E-05
Console.WriteLine($“{fiveDecimalPlaces:G0}”);//产出1E-05

您可能没有意识到这一点,但在处理
params
参数时,您不必显式构造数组。因此,您可以只编写
TrimEnd('0')
(注意:传递的是单个
char
,而不是
char[]
)。@Dan Tao:谢谢,我忘了这一点。我已经有一段时间没有用C了。虽然这两个版本都可以使用,但我已经编辑了我的文章。@Mervin:您需要传递一个
char
,而不是
string
(所以:单引号,而不是双引号)。我为您修复了它——希望您不会介意。您的解决方案将生成类似“2”的输出,当它只得到零时。然后我建议调用.ToString().TrimEnd('0').TrimEnd('.')。另外,与其使用“.”,不如使用CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator使其工作