删除尾随零

时间:2010-12-24 10:48:23

标签: c# .net decimal

我有一些集合返回的字段为

2.4200
2.0044
2.0000

我想要像

这样的结果
2.42
2.0044
2

我尝试使用String.Format,但它会返回2.0000,并将其设置为N0也会对其他值进行舍入。

20 个答案:

答案 0 :(得分:175)

我遇到了同样的问题但是在我无法控制输出到字符串的情况下,这是由库来处理的。在查看Decimal类型的实现细节之后(参见http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx), 我提出了一个巧妙的技巧(这里作为扩展方法):

public static decimal Normalize(this decimal value)
{
    return value/1.000000000000000000000000000000000m;
}

小数的指数部分减少到所需的数量。在输出小数上调用ToString()将写入数字而不会有任何尾随0.例如。

1.200m.Normalize().ToString();

答案 1 :(得分:146)

如果输入是一个字符串,它不是这么简单吗?您可以使用以下方法之一:

string.Format("{0:G29}", decimal.Parse("2.0044"))

decimal.Parse("2.0044").ToString("G29")

2.0m.ToString("G29")

这适用于所有输入。

更新查看Standard Numeric Formats我必须明确将精确说明符设置为29,因为文档明确说明:

  

但是,如果数字是十进制并且省略了精度说明符,则始终使用定点表示法并保留尾随零

评论中

更新 Konrad pointed out

  

注意0.000001等值。 G29格式将以最短的方式呈现它们,因此它将切换到指数表示法。 string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))会将“1E-08”作为结果。

答案 2 :(得分:78)

在我看来,使用Custom Numeric Format Strings更安全。

decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13

答案 3 :(得分:26)

我使用此代码来避免“G29”科学记数法:

public static string DecimalToString(decimal dec)
{
    string strdec = dec.ToString(CultureInfo.InvariantCulture);
    return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}

答案 4 :(得分:12)

使用散列(#)符号仅在必要时显示尾随0。请参阅下面的测试。

decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;

num1.ToString("0.##");       //13.15%
num2.ToString("0.##");       //49.1%
num3.ToString("0.##");       //30%

答案 5 :(得分:9)

我找到了http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/

的优雅解决方案

基本上

十进制v = 2.4200M;

v.ToString( “#######”); //将返回2.42。 #的数量是您支持的十进制数。

答案 6 :(得分:3)

这将有效:

decimal source = 2.4200m;
string output = ((double)source).ToString();

或者,如果您的初始值为string

string source = "2.4200";
string output = double.Parse(source).ToString();

注意this comment

答案 7 :(得分:1)

取决于您的号码代表什么以及您希望如何管理这些值:它是一种货币,您是否需要舍入或截断,您是否只需要将此四舍五入用于显示?

如果要显示,请考虑格式化数字是x.ToString(“”)

http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

http://msdn.microsoft.com/en-us/library/0c899ak8.aspx

如果只是四舍五入,请使用需要MidPointRounding重载的Math.Round重载

http://msdn.microsoft.com/en-us/library/ms131274.aspx

如果从数据库中获取值,请考虑转换而不是转换: double value =(decimal)myRecord [“columnName”];

答案 8 :(得分:1)

这个怎么样:

public static string TrimEnd(this decimal d)
    {
        string str = d.ToString();
        if (str.IndexOf(".") > 0)
        {
            str = System.Text.RegularExpressions.Regex.Replace(str.Trim(), "0+?$", " ");
            str = System.Text.RegularExpressions.Regex.Replace(str.Trim(), "[.]$", " ");
        }
        return str;
    }

答案 9 :(得分:1)

一种非常低级的方法,但我相信这只是使用快速整数计算(并且没有慢速字符串解析和文化敏感方法)的最高性能方式:

public static decimal Normalize(this decimal d)
{
    int[] bits = decimal.GetBits(d);

    int sign = bits[3] & (1 << 31);
    int exp = (bits[3] >> 16) & 0x1f;

    uint a = (uint)bits[2]; // Top bits
    uint b = (uint)bits[1]; // Middle bits
    uint c = (uint)bits[0]; // Bottom bits

    while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
    {
        uint r;
        a = DivideBy10((uint)0, a, out r);
        b = DivideBy10(r, b, out r);
        c = DivideBy10(r, c, out r);
        exp--;
    }

    bits[0] = (int)c;
    bits[1] = (int)b;
    bits[2] = (int)a;
    bits[3] = (exp << 16) | sign;
    return new decimal(bits);
}

private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
    ulong total = highBits;
    total <<= 32;
    total = total | (ulong)lowBits;

    remainder = (uint)(total % 10L);
    return (uint)(total / 10L);
}

答案 10 :(得分:0)

非常简单的答案是使用TrimEnd()。结果如下,

double value = 1.00;
string output = value.ToString().TrimEnd('0');

输出为1 如果我的值是1.01那么我的输出将是1.01

答案 11 :(得分:0)

如果要保留小数,请尝试以下示例:

number = Math.Floor(number * 100000000) / 100000000;

答案 12 :(得分:0)

这很简单。

decimal decNumber = Convert.ToDecimal(value);
        return decNumber.ToString("0.####");

经过测试。

干杯:)

答案 13 :(得分:0)

尝试做更友好的DecimalToString(https://stackoverflow.com/a/34486763/3852139)解决方案:

private static decimal Trim(this decimal value)
{
    var s = value.ToString(CultureInfo.InvariantCulture);
    return s.Contains(CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator)
        ? Decimal.Parse(s.TrimEnd('0'), CultureInfo.InvariantCulture)
        : value;
}

private static decimal? Trim(this decimal? value)
{
    return value.HasValue ? (decimal?) value.Value.Trim() : null;
}

private static void Main(string[] args)
{
    Console.WriteLine("=>{0}", 1.0000m.Trim());
    Console.WriteLine("=>{0}", 1.000000023000m.Trim());
    Console.WriteLine("=>{0}", ((decimal?) 1.000000023000m).Trim());
    Console.WriteLine("=>{0}", ((decimal?) null).Trim());
}

输出:

=>1
=>1.000000023
=>1.000000023
=>

答案 14 :(得分:0)

这是我写的一个扩展方法,如果它是最后一个字符(在删除零之后),它也会删除逗号

public static string RemoveZeroTail(this decimal num)
{
    var result = num.ToString().TrimEnd(new char[] { '0' });
    if (result[result.Length - 1].ToString() == "." || result[result.Length - 1].ToString() == ",")
    {
        return result.Substring(0, result.Length - 1);
    }
    else
    {
        return result;
    }
}

答案 15 :(得分:-1)

您可以设置为:

decimal decNumber = 23.45600000m;
Console.WriteLine(decNumber.ToString("0.##"));

答案 16 :(得分:-1)

以下代码可用于不使用字符串类型:

int decimalResult = 789.500
while (decimalResult>0 && decimalResult % 10 == 0)
{
    decimalResult = decimalResult / 10;
}
return decimalResult;

返回789.5

答案 17 :(得分:-2)

试试这段代码:

string value = "100";
value = value.Contains(".") ? value.TrimStart('0').TrimEnd('0').TrimEnd('.') : value.TrimStart('0');

答案 18 :(得分:-2)

截断尾随零非常容易,使用双面转换解析:

        decimal mydecimal = decimal.Parse("1,45000000"); //(I)
        decimal truncate = (decimal)(double)mydecimal;   //(II)

(I) - &gt;从任何字符串源解析十进制值。

(II) - &gt;首先:强制转换为双倍删除尾随零。          第二:其他强制转换为十进制,因为不存在从十进制到双精度的隐式转换,反之亦然)

答案 19 :(得分:-10)

试试这个

string s = "2.4200";

s = s.TrimStart('0').TrimEnd('0', '.');

然后将其转换为float