3

In Java you can use BigDecimal.stripTrailingZeros() to remove any extra zeros at the end.

I've read a few questions on here about how to strip trailing zeros from a decimal in C# but none of them seem to offer correct solutions.

This question for example the answer of doing ToString("G") doesn't always work.

Ideally I would like a function that does decimal -> decimal with the new decimal having the least scale possible without losing any info or removing any trailing zeros.

Is there any way to do this easily? Or would it involve fiddling around with decimal.GetBits()?

EDIT: Should also add I have i18n to worry about so doing string manipulation on the result isn't ideal because of differences in decimal separators.

Community
  • 1
  • 1
Mike Q
  • 22,839
  • 20
  • 87
  • 129
  • 2
    well the answer that mentions trimming seems more effective and should work in all cases.. use that http://stackoverflow.com/questions/4525854/remove-trailing-zeroes/4525896#4525896 – Shekhar_Pro Feb 21 '11 at 14:43
  • 1
    Check out Marc Gravell's answer in this post: http://stackoverflow.com/questions/2714645/decimal-truncate-trailing-zeros. It does decimal to decimal just as you asked. – Doctor Jones Feb 21 '11 at 14:51
  • @Shekhar: Actually, the answers in that question using trimming are badly broken. – Ben Voigt Feb 21 '11 at 15:02
  • @DoctaJonez - Unfortunately that answer doesn't strip the zeros. I have ToString() -> 1000.0000 beforehand and ToString() -> 1000.0000 afterwards. – Mike Q Feb 21 '11 at 15:17

3 Answers3

2

How about Decimal.Parse(d.ToString("0.###########################"))?

Gabe
  • 84,912
  • 12
  • 139
  • 238
1

Here is what i have come up with (Crazy code but works smoothly)

private decimal Normalize(decimal d)
{
    string[] tmp = d.ToString().Split('.');
    string val = tmp[0];    
    string fraction = null;
    decimal result;
    if(tmp.Length > 1) fraction = tmp[1];
    if(fraction != null && Getleast(fraction) > 0) 
    {
        decimal.TryParse(val.ToString() + "." + fraction.TrimEnd('0').ToString(),out result);
    }
    else
    {
        return decimal.Parse(val);
    }
    return result;
}

private decimal Getleast(string str)
{
    decimal res;
    decimal.TryParse(str.TrimEnd('0'),out res);// It returns 0 even if we pass null or empty string
    return res;
}

Here are sample Input:

Console.WriteLine(Normalize(0.00M));
Console.WriteLine(Normalize(0.10M));
Console.WriteLine(Normalize(0001.00M));
Console.WriteLine(Normalize(1000.01M));
Console.WriteLine(Normalize(1.00001230M));
Console.WriteLine(Normalize(0031.200M));        
Console.WriteLine(Normalize(0.0004000M));
Console.WriteLine(Normalize(123));

And respective output:

0
0.1
1
1000.01
1.0000123
31.2
0.0004
123
Shekhar_Pro
  • 18,056
  • 9
  • 55
  • 79
  • Not quite so simple, you need to check for the presence of a decimal point first. Otherwise you end up with ridiculous results like http://ideone.com/DXokE – Ben Voigt Feb 21 '11 at 14:58
  • yeah i am working on my LINQPAD to get somthing working with strings... till then maybe marks answer is good – Shekhar_Pro Feb 21 '11 at 15:07
0

Not the most elegant of solutions but it should do everything you need.

 private decimal RemoveTrailingZeros(decimal Dec)
    {
        string decString = Dec.ToString();

        if (decString.Contains("."))
        {
            string[] decHalves = decString.Split('.');

            int placeholder = 0, LoopIndex = 0;

            foreach (char chr in decHalves[1])
            {
                LoopIndex++;
                if (chr != '0')
                    placeholder = LoopIndex;
            }

            if (placeholder < decHalves[1].Length)
                decHalves[1] = decHalves[1].Remove(placeholder);

            Dec = decimal.Parse(decHalves[0] + "." + decHalves[1]);
        }

        return Dec;
    }

Fixed version, Thanks Shekhar_Pro!

BenE
  • 67
  • 5
  • it failed for `RemoveTrailingZeros(1000.01M)` at line `decHalves[1] = decHalves[1].Remove(placeholder);``ArgumentOutOfRangeException` Exception – Shekhar_Pro Feb 21 '11 at 16:16
  • in decimal we don't have any i18n issues.. it comes when we convert it to string.. you can always have culture neutral string conversion for this particular processing... – Shekhar_Pro Feb 21 '11 at 16:27