5

I've got a pretty compact way of removing trailing zeros in decimal values but I'd prefer a way that doesn't involve string roundtripping as mine currently does. This is my current solution:

var value = 0.010m;
value = decimal.Parse(value.ToString("G29"));
Console.WriteLine(value); // prints 0.01 (not 0.010)

So it works, but do you have an even better way?

Also, as a secondary question is decimalValue.ToString() 100% conformant to xs:decimal?

Bent Rasmussen
  • 5,538
  • 9
  • 44
  • 63
  • 1
    - Of course I could repeatedly truncate and compare decimals until values are no longer equal. At least (0.010m == 0.01m) – Bent Rasmussen Aug 22 '11 at 11:38
  • 2
    Related question: http://stackoverflow.com/questions/3683718/is-there-a-way-to-get-the-significant-figures-of-a-decimal – Thomas Levesque Aug 22 '11 at 11:52
  • 2
    The best way to do it is with Jon's answer to the same question here: http://stackoverflow.com/questions/4298719/parse-decimal-and-filter-extra-0-on-the-right/4298787#4298787 – Gabe Aug 22 '11 at 12:03
  • Thanks Gabe & Thomas. This looks just like what I'm looking for, albeit quite a lot of code needed, but I'll take it. :-) – Bent Rasmussen Aug 22 '11 at 12:06
  • Oh, it requires BigInteger from .NET 4.0. That's a showstopper. – Bent Rasmussen Aug 22 '11 at 12:10
  • 3
    Possible duplicate of [Remove trailing zeros](http://stackoverflow.com/questions/4525854/remove-trailing-zeros) - which has a great answer, too: http://stackoverflow.com/a/7983330/709537 – Evgeniy Berezovsky Oct 02 '16 at 23:06

4 Answers4

2

It doesn't really matter how many SF the number is stored as but rather what happens when you output it.

Try

// The number of #'s is the number of decimal places you want to display
Console.WriteLine(value.ToString("0.###############");
// Prints 0.01
John Oxley
  • 14,698
  • 18
  • 53
  • 78
1

To answer your second question, System.XmlConvert.ToString(decimal value) is 100% conformant to xs:decimal.

This should be slightly faster.

public static decimal StripTrailingZeroes(this decimal value)
{
    return decimal.Parse(value.ToString("G29", CultureInfo.InvariantCulture), CultureInfo.InvariantCulture);
}
Jonathan Dickinson
  • 9,050
  • 1
  • 37
  • 60
  • @Bent - Sorry I can't help with the original problem - I did a half-attempt to figure out how `Decimal` works; it's poorly documented AND it looks like it could be tricky to modify the `int[4]` representation. I would make this an extension method and look at optimizing it later if it becomes a problem; chances are it isn't a big perf hit (sounds like premature optimization). I have edited my question with, what should be, the fastest string round-trip. – Jonathan Dickinson Aug 22 '11 at 12:00
  • 2
    It's just this "splinter in my mind" issue: it shouldn't have to change representation to string to strip the trailing zeroes, so it nags me, but you are quite correct, it should be correct and that's the most important thing. – Bent Rasmussen Aug 22 '11 at 12:03
  • I know it would bug me too. Just look at some of my string manipulation answers - I hate doing stuff with strings. – Jonathan Dickinson Aug 22 '11 at 12:05
1

Here's a new draft idea:

public static class DecimalEx
{
    public static decimal Fix(this decimal value)
    {
        var x = value;
        var i = 28;
        while (i > 0)
        {
            var t = decimal.Round(x, i);
            if (t != x)
                return x;
            x = t;
            i--;
        }
        return x;
    }
}

This might just do it. But it's very rough. Need to test and simplify it.

Bent Rasmussen
  • 5,538
  • 9
  • 44
  • 63
0

Casting to double and back to decimal should work.

decimal fixDecimal(decimal number) => (decimal)(double)number;

Though, there might be edge cases that I'm not aware of.

orad
  • 15,272
  • 23
  • 77
  • 113