Jam*_*aix 25 .net c# floating-point int parsing
在C#中:
抛出一个FormatException,似乎不应该:
Int32.Parse("1,234");
Run Code Online (Sandbox Code Playgroud)
这不,这似乎是正常的:
Single.Parse("1,234");
Run Code Online (Sandbox Code Playgroud)
令人惊讶的是,这解析得很好:
Single.Parse("1,2,3,4"); //Returns 1234
Run Code Online (Sandbox Code Playgroud)
我的本地文化是EN-US,,默认的千位分隔符char也是如此.
主要问题:为什么不一致?
另外:为什么Parse("1,2,3,4")工作?它似乎只是在解析之前删除本地分隔符char的所有实例.我知道在正则表达式检查或类似的东西中会有额外的运行时开销,但什么时候数字文字"1,2,3,4"不是拼写错误?
Ill*_*ack 12
根据MSDN:
s参数包含以下形式的数字:
[WS] [符号]数字[WS]
该小号参数使用NumberStyles.Integer风格解释.除十进制数字外,只允许前导和尾随空格以及前导符号.
就是这样,NumberStyles.Integer不允许Parse方法使用千位分隔符,而Single.Parse默认使用NumberStyles.Float和NumberStyles.AllowThousands.您可以通过将第二个参数指定为NumberStyles来更改此行为:
Int32.Parse("1,234", NumberStyles.AllowThousands); //works
Run Code Online (Sandbox Code Playgroud)
Single.Parse忽略分组,根本不使用特定于文化的NumberGroupSizes,并且仅确定该字符是组还是小数分隔符.组大小仅在格式化数字时使用.
Ian*_*Ian 11
对于第一种情况,从Microsoft源代码参考,默认情况下Int32.Parse实现NumberStyles.Integer但不实现NumberStyles.AllowThousands
public static int Parse(String s) {
return Number.ParseInt32(s, NumberStyles.Integer, NumberFormatInfo.CurrentInfo);
}
Run Code Online (Sandbox Code Playgroud)
因此不允许使用任何逗号分隔符.这个:
Int32.Parse("1,234");
Run Code Online (Sandbox Code Playgroud)
要么
Int32.Parse("1.234");
Run Code Online (Sandbox Code Playgroud)
两者都错了.在任何文化中.
要修复它,NumberStyles.AllowThousands必须添加到NumberStyles将允许在EN-US文化中解析"1,234" :
Int32.Parse("1,234", NumberStyles.Integer | NumberStyles.AllowThousands);
Run Code Online (Sandbox Code Playgroud)
但
Int32.Parse("1.234", NumberStyles.Integer | NumberStyles.AllowThousands);
Run Code Online (Sandbox Code Playgroud)
还是会throw的Exception.
对于第二种情况,根据Microsoft Code Source Reference,默认样式为Single.Parse:
public static float Parse(String s) {
return Parse(s, NumberStyles.Float | NumberStyles.AllowThousands, NumberFormatInfo.CurrentInfo);
}
Run Code Online (Sandbox Code Playgroud)
这允许千位分隔符.并且","在EN-US文化中被认为是千分隔符Single.Parse,因此您可以正确解析第二种情况
Single.Parse("1,234"); //OK
Run Code Online (Sandbox Code Playgroud)
显然"1.234"也是正确的,除了"." 不被识别为千位分隔符而是小数分隔符.
至于第三种情况,内部,Single.Parse调用TryStringToNumber和Parse.Number,它们会忽略千位分隔符.这样你得到:
Single.Parse("1,2,3,4"); //Returns 1234
Run Code Online (Sandbox Code Playgroud)
因为它相当于
Single.Parse("1234"); //Returns 1234
Run Code Online (Sandbox Code Playgroud)