Number parsing weirdness
This line of code:
Console.WriteLine(Convert.ToInt32(“23,23”) + 1);
Throws an exception. This line of code:
Console.WriteLine(Convert.ToDouble(“23,23”) + 1);
Prints 2324.
Does anybody know why this is 开发者_运维知识库the case? I wouldn't think that anything good could come of the second conversion.
From the MSDN documentation of System.Double.Parse:
The s parameter can contain [...] a string of the form:
[ws][sign][integral-digits[,]]integral-digits[.[fractional-digits]][e[sign]exponential-digits][ws]
Here, the comma (,
) stands for "[a] culture-specific thousands separator symbol".
To summarize: If your current culture's thousands separator symbol appears anywhere in the string, it is ignored by Double.Parse
(which is invoked internally by Convert.ToDouble
).
Int32.Parse(string), on the other hand, does not allow thousands separators in the string:
[ws][sign]digits[ws]
which is why your first example throws an exception. You can change this behavior for both Double.Parse
and Int32.Parse
by using an overload that allows you to specify NumberStyles
, as explained by the other answers.
The first fails because int.Parse
doesn't allow the thousands separator by default. You can change that using NumberStyles:
int d = int.Parse("11,23",
NumberStyles.AllowThousands,
CultureInfo.InvariantCulture);
Now it works like the double version which does support thousands separators by default. They presumably succeed because "," when treated as a thousands separator by the parser is completely ignored - even though the comma sometimes doesn't make sense as a thousands separator.
Surprisingly, even this works:
double d = double.Parse("1,,1,2,3", CultureInfo.InvariantCulture);
In the above, d is set to the value 1123.0.
Console.WriteLine(Convert.ToDouble(“23,23”) + 1);
In this case, the comma is being interpreted as your localization's group separator symbol, and is ignored. See http://msdn.microsoft.com/en-us/library/fd84bdyt.aspx.
Console.WriteLine(Convert.ToInt32(“23,23”) + 1);
In this case, you are using Int32.Parse
, which doesn't support group separators by default.
The reasoning behind this is that the integer converter has no localization support by default, because localization adds an additional overhead and there is no reason to add it for a parser that doesn't need to interact with any symbols at all. You can, however, force the parser to support localization with some extra arguments:
int.Parse("11,23", NumberStyles.AllowThousands, CultureInfo.InvariantCulture);
Float/double conversion, on the other hand, have to support a decimal separator. In some cultures, this is ","
, in others, it can be " "
or "."
. Since the function must support localization anyway, it would make no sense for it to only support some localization features by default. Otherwise, the implementation would confuse people who expect that since localization is supported for decimal separator, it would support other localization aspects as well.
Commas are ignored in the conversion to double. If you would like commas to generate an error, then you can use the Double.Parse(string, System.Globalization.NumberStyles) method.
Because the double is assuming that the comma is a thousands separater, and ignores it. The Int32 Convert does not do that.
?double.Parse("23,23", System.Globalization.CultureInfo.InstalledUICulture);
23.23
?double.Parse("23,23", new System.Globalization.CultureInfo("en-US"));
2323.0
?double.Parse("23,23", new System.Globalization.CultureInfo("fr-FR"));
23.23
?double.Parse("23,23", System.Globalization.CultureInfo.InvariantCulture);
2323.0
the same thing for Convert.ToDouble:
?Convert.ToDouble("23,23", System.Globalization.CultureInfo.InvariantCulture);
2323.0
精彩评论