代码之家  ›  专栏  ›  技术社区  ›  quillbreaker

数字解析怪诞

c#
  •  9
  • quillbreaker  · 技术社区  · 15 年前

    这一行代码:

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

    引发异常。 这一行代码:

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

    打印2324。

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

    6 回复  |  直到 15 年前
        1
  •  14
  •   Heinzi    15 年前

    the MSDN documentation of System.Double.Parse :

    s参数可以包含形式为“…”的字符串:

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

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

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


    Int32.Parse(string) 另一方面,字符串中不允许有数千个分隔符:

    [ws][sign]digits[ws]
    

    这就是您的第一个示例抛出异常的原因。你可以改变这两种行为 双解析 Int32.Parse 通过使用允许您指定 NumberStyles 如其他答案所述。

        2
  •  8
  •   Mark Byers    15 年前

    第一次失败是因为 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。

        3
  •  6
  •   David Pfeffer    15 年前
    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);
    

    另一方面,浮动/双重转换, 以支持十进制分隔符。在某些文化中,这是 "," ,在其他方面,它可以 " " "." .因为函数无论如何都必须支持本地化,所以默认情况下只支持一些本地化特性是没有意义的。否则,实现会使人们感到困惑,因为本地化支持十进制分隔符,所以它也支持其他本地化方面。

        4
  •  1
  •   Jeffrey L Whitledge    15 年前

    在转换为double时忽略逗号。如果希望逗号生成错误,则可以使用double.parse(string,system.globalization.numberstyles)方法。

        5
  •  0
  •   Charles Bretana    15 年前

    因为double假定逗号是一个数千分隔符,而忽略了它。Int32转换不能做到这一点。

        6
  •  0
  •   serhio    15 年前
    ?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
    

    同样的事情 转换.todouble :

    ?Convert.ToDouble("23,23", System.Globalization.CultureInfo.InvariantCulture);
    2323.0