C# 浮点数解析:是否有 Catch All 算法?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/192/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Floating Point Number parsing: Is there a Catch All algorithm?
提问by Michael Stum
One of the fun parts of multi-cultural programming is number formats.
多元文化编程的有趣部分之一是数字格式。
- Americans use 10,000.50
- Germans use 10.000,50
- French use 10 000,50
- 美国人使用 10,000.50
- 德国人使用 10.000,50
- 法语使用 10 000,50
My first approach would be to take the string, parse it backwards until I encounter a separator and use this as my decimal separator. There is an obvious flaw with that: 10.000 would be interpreted as 10.
我的第一种方法是获取字符串,向后解析它,直到遇到分隔符并将其用作我的小数分隔符。这有一个明显的缺陷:10.000 会被解释为 10。
Another approach: if the string contains 2 different non-numeric characters, use the last one as the decimal separator and discard the others. If I only have one, check if it occurs more than once and discards it if it does. If it only appears once, check if it has 3 digits after it. If yes, discard it, otherwise, use it as decimal separator.
另一种方法:如果字符串包含 2 个不同的非数字字符,则使用最后一个作为小数点分隔符并丢弃其他字符。如果我只有一个,请检查它是否出现多次,如果出现则将其丢弃。如果它只出现一次,检查它后面是否有 3 位数字。如果是,则丢弃它,否则,将其用作小数点分隔符。
The obvious "best solution" would be to detect the User's culture or Browser, but that does not work if you have a Frenchman using an en-US Windows/Browser.
显而易见的“最佳解决方案”是检测用户的文化或浏览器,但如果您有法国人使用 en-US Windows/浏览器,这将不起作用。
Does the .net Framework contain some mythical black magic floating point parser that is better than Double.(Try)Parse()
in trying to auto-detect the number format?
.net 框架是否包含一些比Double.(Try)Parse()
尝试自动检测数字格式更好的神秘黑魔法浮点解析器?
采纳答案by Ryan Fox
I think the best you can do in this case is to take their input and then show them what you think they meant. If they disagree, show them the format you're expecting and get them to enter it again.
我认为在这种情况下你能做的最好的事情就是听取他们的意见,然后向他们展示你认为他们的意思。如果他们不同意,请向他们展示您期望的格式,并让他们再次输入。
回答by huseyint
I don't know the ASP.NET side of the problem but .NET has a pretty powerful class: System.Globalization.CultureInfo. You can use the following code to parse a string containing a double value:
我不知道问题的 ASP.NET 方面,但 .NET 有一个非常强大的类:System.Globalization.CultureInfo。您可以使用以下代码来解析包含双精度值的字符串:
double d = double.Parse("100.20", CultureInfo.CurrentCulture);
// -- OR --
double d = double.Parse("100.20", CultureInfo.CurrentUICulture);
If ASP.NET somehow (i.e. using HTTP Request headers) passes current user's CultureInfo to either CultureInfo.CurrentCulture or CultureInfo.CurrentUICulture, these will work fine.
如果 ASP.NET 以某种方式(即使用 HTTP 请求标头)将当前用户的 CultureInfo 传递给 CultureInfo.CurrentCulture 或 CultureInfo.CurrentUICulture,这些将正常工作。
回答by Chris Marasti-Georg
You can't please everyone. If I enter ten as 10.000, and someone enters ten thousand as 10.000, you cannot handle that without some knowledge of the culture of the input. Detect the culture somehow (browser, system setting - what is the use case? ASP? Internal app, or open to the world?), or provide an example of the expected formatting, and use the most lenient parser you can. Probably something like:
你不能取悦所有人。如果我输入 10 为 10.000,而有人输入 10000 为 10.000,如果不了解输入的文化,您将无法处理。以某种方式检测文化(浏览器、系统设置 - 用例是什么?ASP?内部应用程序,还是对世界开放?),或提供预期格式的示例,并使用最宽松的解析器。大概是这样的:
double d = Double.Parse("5,000.00", NumberStyles.Any, CultureInfo.InvariantCulture);
回答by Michiel de Mare
The difference between 12.345 in French and English is a factor of 1000. If you supply an expected range where max < 1000*min, you can easily guess.
法语和英语中的 12.345 之间的差异是 1000 的因数。如果您提供 max < 1000*min 的预期范围,您很容易猜到。
Take for example the height of a person (including babies and children) in mm.
以人(包括婴儿和儿童)的身高为例,单位为毫米。
By using a range of 200-3000, an input of 1.800 or 1,800 can unambiguously be interpreted as 1 meter and 80 centimeters, whereas an input of 912.300 or 912,300 can unambiguously be interpreted as 91 centimeters and 2.3 millimeters.
通过使用 200-3000 的范围,输入 1.800 或 1,800 可以明确解释为 1 米和 80 厘米,而输入 912.300 或 912,300 可以明确解释为 91 厘米和 2.3 毫米。