Parsing Culture-Invariant Floating-Point Numbers

I just came across this non-obvious behavior of double.TryParse:

We develop on German Windows, but the input field for float values should be intelligent to recognize both German (“,”) and international (“.”) notations for the decimal point.

Of course the functions to call to parse a string s into a double value are:

double f; string s = "double value as string";

double.TryParse(s, System.Globalization.NumberStyles.Float,
    System.Globalization.CultureInfo.InvariantCulture, out f)

double.TryParse(s, out f)

But the results were surprising

InvariantCulture default culture
string value return (bool) output (double) return (bool) output (double)
“100,03” false true 100.03
“100.03” true 100.03 true 10003.0

My reasoning was, that if current (UI) culture could not parse the string, I let Invariant Culture try to parse it.

It turns out, however, that if the current culture simply removes all characters it does not recognize as valid input string for float numbers, and then parses the string, with the undesired result as seen above.

So the right way seems to try with invariant culture first, then use current culture:

double f;
double? Result;
if (double.TryParse(s, System.Globalization.NumberStyles.Float,
        System.Globalization.CultureInfo.InvariantCulture, out f))
    Result = f;
else if (double.TryParse(s, out f))
    Result = f;
    Result = null;

1 thought on “Parsing Culture-Invariant Floating-Point Numbers

  1. “try with invariant culture first, then use current culture”
    Maybe it is wrong. Because German float “1,2” converts to “12” with invariant culture and throw no exeption, because comma in invariant culture is thousand separator.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.