Decimal.Parse throws a FormatException
Asked Answered
S

2

5

I tried to use the decimal.parse as described at : http://msdn.microsoft.com/en-us/library/cafs243z(v=vs.110).aspx

So i copied from this page the following example:

   string value;
   decimal number;
   value = "1.62345e-02";
   try
   {
       number = Decimal.Parse(value);
       Console.WriteLine("'{0}' converted to {1}.", value, number);
   }
   catch (FormatException)
   {
       Console.WriteLine("Unable to parse '{0}'.", value);
   }

And i got a FormatException, Do you have an idea why it's happened?

thanks, eyal

Sandblast answered 12/5, 2014 at 8:50 Comment(3)
Wrong Locale for the thread, expecting a , instead of a .???Agranulocytosis
specify the CultureInfo in the Parse.Glottic
I'm pretty sure Decimal.Parse doesn't handle e notation by default - the documentation you copied this from even tells you this won't work.Chrystalchryste
B
6

Try this:

using System.Globalization;
using System.Text;

....

number = Decimal.Parse(value, NumberStyles.AllowExponent|NumberStyles.AllowDecimalPoint);

In order to parse a number in exponential format, you need to set the appropriate flags from NumberStyles Enumeration as described here.

Bouchard answered 12/5, 2014 at 8:55 Comment(0)
S
10

shree.pat18's answer is of course right. But I want to explain this question a little bit more if you let me..

Let's look at how Decimal.ToParse(string) method implemented;

public static Decimal Parse(String s)
{
   return Number.ParseDecimal(s, NumberStyles.Number, NumberFormatInfo.CurrentInfo);
}

As you can see, this method uses NumberStyles.Number by default. It is a composite number style and it's implemented like;

Number   = AllowLeadingWhite | AllowTrailingWhite | AllowLeadingSign | AllowTrailingSign |
           AllowDecimalPoint | AllowThousands,

That means your string can have one of;

Since NumberStyles.Number has AllowDecimalPoint, it fits . in your string but this style doesn't have AllowExponent that's why it can't parse e-02 in your string.

That's why you need to use Decimal.Parse Method (String, NumberStyles) overload since you can specify NumberStyles yourself.

Selfconscious answered 12/5, 2014 at 11:6 Comment(6)
Thanks @SergeyBerezovskiy I try to teach him how to fish instead of give him a fish.Glazier
In most cases (e.g. input coming from files) you will also want to use NumberFormatInfo.InvariantInfo, that is use the overload Parse(String, NumberStyles, IFormatProvider). Regardless of whether you want to use the system culture or an invariant culture case it's best to be specific and pass a NumberFormatInfo argument. The next developer can see immediately what format of decimal points etc. is expected.Cremona
@AndersForsgren Unfortunately, OP never told use what his CurrentCulture exactly. That's why I assume his culture uses . as a NumberDecimalSeparator of his current culture. You have a point about using IFormatProvider would be more clear in most cases. But InvariantInfo is culture-independent. It uses InvariantCulture settings. That's why always using InvariantInfo might not be a good idea. Of course these all depends on inputs.Glazier
+1 for the detailed answer and an implicit +1 for the philosophy behind it.Bouchard
@SonerGönül I agree we need more details here, but regardless, it is good to be explicit: I recommend passing CurrentCulture even if it is equivalent to omitting the argument. As for Current vs. Invariant, I find 99% of bugs (almost weekly, since I work in a culture with decimal comma) are due to code that didn't think about it and used default (system culture) even though what they meant was to use an InvariantCulture. The opposite kind of bug I have almost never seen!Cremona
@AndersForsgren If you say so :)Glazier
B
6

Try this:

using System.Globalization;
using System.Text;

....

number = Decimal.Parse(value, NumberStyles.AllowExponent|NumberStyles.AllowDecimalPoint);

In order to parse a number in exponential format, you need to set the appropriate flags from NumberStyles Enumeration as described here.

Bouchard answered 12/5, 2014 at 8:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.