数字解析怪异

时间:2010-01-19 14:47:42

标签: c#

这行代码:

Console.WriteLine(Convert.ToInt32(“23,23”) + 1);

引发异常。 这行代码:

Console.WriteLine(Convert.ToDouble(“23,23”) + 1);

打印2324。

有人知道为什么会这样吗?我不认为第二次转换会带来任何好处。

6 个答案:

答案 0 :(得分:14)

来自the MSDN documentation of System.Double.Parse

  

s参数可以包含以下形式的字符串:

     

[ws][sign][integral-digits[,]]integral-digits[.[fractional-digits]][e[sign]exponential-digits][ws]

这里,逗号(,)代表“[a]特定于文化的千位分隔符号”。

总结一下:如果当前文化的千位分隔符号出现在字符串中的任何位置,Double.Parse(由Convert.ToDouble在内部调用)会忽略它。


另一方面,

Int32.Parse(string)不允许字符串中包含数千个分隔符:

[ws][sign]digits[ws]

这就是你的第一个例子抛出异常的原因。您可以使用允许您指定Double.Parse的重载来更改Int32.ParseNumberStyles的此行为,如其他答案所述。

答案 1 :(得分:8)

第一个失败,因为int.Parse默认情况下不允许千位分隔符。您可以使用NumberStyles更改它:

int d = int.Parse("11,23",
                  NumberStyles.AllowThousands,
                  CultureInfo.InvariantCulture);

现在它的工作方式与默认情况下 支持千位分隔符的双重版本相同。它们可能成功,因为“,”被解析器视为千位分隔符时被完全忽略 - 即使逗号有时作为千位分隔符没有意义。

令人惊讶的是,即便如此:

double d = double.Parse("1,,1,2,3", CultureInfo.InvariantCulture);

在上面,d设置为值1123.0。

答案 2 :(得分:6)

Console.WriteLine(Convert.ToDouble(“23,23”) + 1);

在这种情况下,逗号被解释为本地化的组分隔符号,并被忽略。请参阅http://msdn.microsoft.com/en-us/library/fd84bdyt.aspx

Console.WriteLine(Convert.ToInt32(“23,23”) + 1);

在这种情况下,您使用的是Int32.Parse,默认情况下不支持组分隔符。

这背后的原因是整数转换器默认情况下没有的本地化支持,因为本地化会增加额外的开销,没有理由将它添加到不需要交互的解析器中任何符号都可以。但是,您可以通过一些额外的参数强制解析器支持本地化:

int.Parse("11,23", NumberStyles.AllowThousands, CultureInfo.InvariantCulture);

浮点/双转换,另一方面, 支持小数点分隔符。在某些文化中,这是",",在其他文化中,它可以是" ""."。由于该功能必须支持本地化,因此默认情况下仅支持某些本地化功能是没有意义的。否则,实施会使那些期望因为小数分隔符支持本地化的人感到困惑,它也会支持其他本地化方面。

答案 3 :(得分:1)

在转换为double时忽略逗号。如果您希望逗号生成错误,则可以使用Double.Parse(string,System.Globalization.NumberStyles)方法。

答案 4 :(得分:0)

因为double假设逗号是千位分隔符,并忽略它。 Int32转换不会那样做。

答案 5 :(得分:0)

?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

Convert.ToDouble

也是如此
?Convert.ToDouble("23,23", System.Globalization.CultureInfo.InvariantCulture);
2323.0