2

I have a string "-6.379885574693132E-10" that I can't convert to decimal..is it to big? Is it possible to work around this?

Error:

Input string was not correct format

public class Program {
    private static void Main(string[] args) {
        Foo foo = new Foo();
        var str = "-6.379885574693132E-10";
        foo.SetPropertyValue("myVal", str);
    }
}

public class Foo {

    public decimal myVal { get; set; }

    public void SetPropertyValue(string propertyName, object value) {
        var propertyInfo = GetType().GetProperty(propertyName);
        propertyInfo.SetValue(this,
            Convert.ChangeType(value, propertyInfo.PropertyType, CultureInfo.InvariantCulture), null);
    }
}
MrProgram
  • 5,044
  • 13
  • 58
  • 98
  • 1
    Have you tried `decimal.Parse`? – i486 Jan 21 '16 at 11:39
  • 1
    Why do you need reflection at all? – Tim Schmelter Jan 21 '16 at 11:40
  • @TimSchmelter This is just a small example, it's needed in my case. – MrProgram Jan 21 '16 at 11:42
  • 1
    @emptyman Note that `Convert.ChangeType("-6.379885574693132E-10", TypeCode.Object).GetType().FullName;` returns `System.String`. you are attempting to assign `string` to `decimal` – tchelidze Jan 21 '16 at 11:42
  • Your question boils down to: Why does `Convert.ChangeType("-6.379885574693132E-10", typeof(decimal), CultureInfo.InvariantCulture);` throw? – Jeppe Stig Nielsen Jan 21 '16 at 11:49
  • @JeppeStigNielsen Well, yes it looks like it – MrProgram Jan 21 '16 at 11:51
  • 1
    Convert.ChangeType's job is to cast one type to another, not parse text. When converting text to a numeric type, it will use the current culture's numeric format. To parse a type, use that type's `Parse` method, if available. In this case, use `decimal.Parse` – Panagiotis Kanavos Jan 21 '16 at 11:53
  • The answer to the boiled-down question appears to be: `IConvertible` infrastructure and `Convert` static methods implicitly use `NumberStyles.Number` when converting from a `string` to a `decimal`, and your value has "scientific notation" (`E-10`) in it, so it does not conform to that. This notation is not one normally used for `decimal`, i.e. no `decimal` will have this scientific suffix in its _standard_ representation as a formatted string. **Addition:** It is the same with `Convert.ToDecimal("-6.379885574693132E-10", CultureInfo.InvariantCulture);` of course, it throws as well. – Jeppe Stig Nielsen Jan 21 '16 at 11:57
  • Is it possible to work around with reflection? – MrProgram Jan 21 '16 at 12:11
  • How general must your solution be. It seems that you once had a `double` which was then converted to a `string` (in that case `E` notation can occur). After that you try converting that string value directly to a third type, `decimal`. Why? You can easily hard-code the case `string` to `decimal` if you do not mind having an explicit special case in your code. But maybe you should avoid going from `double` to `decimal` via `string`? – Jeppe Stig Nielsen Jan 21 '16 at 13:48

1 Answers1

8

I have no knowledge about reflection but you can parse this string with a combination of AllowDecimalPoint, AllowExponent and AllowLeadingSign styles with a culture that has . as a NumberDecimalSeparator like InvariantCulture as;

var s = "-6.379885574693132E-10";
var d = decimal.Parse(s, NumberStyles.AllowDecimalPoint | 
                         NumberStyles.AllowExponent | 
                         NumberStyles.AllowLeadingSign, 
                         CultureInfo.InvariantCulture);

Or more simple, you can use NumberStyles.Float which includes all these styles.

var s = "-6.379885574693132E-10";
var d = decimal.Parse(s, NumberStyles.Float, CultureInfo.InvariantCulture);

enter image description here

Soner Gönül
  • 97,193
  • 102
  • 206
  • 364
  • Soner, is there a way to avoid that google shows MSDN links always in your own language("tr-tr") instead of in english("en-us")? Even if i search f.e. for `NumberStyles enumeration`(so english) i'm getting the german links. That's annoying since i always have to change "de-de" to "en-us". Do you have the same problem? – Tim Schmelter Jan 21 '16 at 12:01
  • @TimSchmelter Maybe that is because your web browser sends a request where it prefers "German (Germany)" over "English (United States)" in its HTTP headers? Some web sites want to answer in the language preferred by the user. Maybe you can change some settings in your web browser? – Jeppe Stig Nielsen Jan 21 '16 at 12:07
  • @TimSchmelter Hmm, honestly, I never get Turkish links. You search on Google or MSDN search by the way? For example, my `CurrentCulture` setting is my local computer is `tr-TR`, I'm not logged in to MSDN with my live account, and when I search in both Google and MSDN search, I always get English links. I use English languaged browser as well, maybe this can cause it. For example Mozilla has: `Settings-->Content-->Languages` section which you can set preferred language option. I'm not %100 sure about this subject. I know that feel by the way, it's annoying. – Soner Gönül Jan 21 '16 at 12:11
  • @TimSchmelter My web browser right here (IE 11) appears to send `"ACCEPT": text/html, application/xhtml+xml, */*` and `"ACCEPT-LANGUAGE": da-DK ` among others. That is "Danish (Denmark)". However, many websites do not offer Danish language versions, and then they fall back to English. – Jeppe Stig Nielsen Jan 21 '16 at 12:11
  • 2
    @JeppeStigNielsen & Soner: thanks to you both. I think that i can't avoid it and that it's not a browser setting(i'm using chrome). I think that it's related to google. I'm always getting localized results(determined by my IP) including german MSDN links. You can't turn off it easily. If i search at `www.google.co.uk` i'll see the english links. Maybe i will try the firefox/chrome extension [GoogleGlobal](https://www.redflymarketing.com/internet-marketing-tools/google-global/) – Tim Schmelter Jan 21 '16 at 12:23
  • The extension works great. http://tinyurl.com/h3hclql – Tim Schmelter Jan 21 '16 at 12:34
  • @TimSchmelter Great! Upvoted your comment so people can find it :) – Soner Gönül Jan 21 '16 at 12:38