Remove trailing zeros

2018-12-31 18:01发布

I have some fields returned by a collection as

2.4200
2.0044
2.0000

I want results like

2.42
2.0044
2

I tried with String.Format, but it returns 2.0000 and setting it to N0 rounds the other values as well.

标签: c# .net decimal
16条回答
伤终究还是伤i
2楼-- · 2018-12-31 18:37

Is it not as simple as this, if the input IS a string? You can use one of these:

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

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

2.0m.ToString("G29")

This should work for all input.

Update Check out the Standard Numeric Formats I've had to explicitly set the precision specifier to 29 as the docs clearly state:

However, if the number is a Decimal and the precision specifier is omitted, fixed-point notation is always used and trailing zeros are preserved

Update Konrad pointed out in the comments:

Watch out for values like 0.000001. G29 format will present them in the shortest possible way so it will switch to the exponential notation. string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US"))) will give "1E-08" as the result.

查看更多
裙下三千臣
3楼-- · 2018-12-31 18:37

try like this

string s = "2.4200";

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

and then convert that to float

查看更多
唯独是你
4楼-- · 2018-12-31 18:39

I ran into the same problem but in a case where I do not have control of the output to string, which was taken care of by a library. After looking into details in the implementation of the Decimal type (see http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx), I came up with a neat trick (here as an extension method):

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

The exponent part of the decimal is reduced to just what is needed. Calling ToString() on the output decimal will write the number without any trailing 0. E.g.

1.200m.Normalize().ToString();
查看更多
十年一品温如言
5楼-- · 2018-12-31 18:40

This does exactly what you want:

If your initial value is decimal:

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

If your initial value is string:

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

And should cost minimum performance.

查看更多
残风、尘缘若梦
6楼-- · 2018-12-31 18:41

A very low level approach, but I belive this would be the most performant way by only using fast integer calculations (and no slow string parsing and culture sensitive methods):

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);
}
查看更多
公子世无双
7楼-- · 2018-12-31 18:44

Use the hash (#) symbol to only display trailing 0's when necessary. See the tests below.

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%
查看更多
登录 后发表回答