wpf 判断字符串到 double/float/int/short/byte 是否超出范围

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18519833/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:32:22  来源:igfitidea点击:

Tell if string to double/float/int/short/byte is out of range

c#wpfinttryparseoutofrangeexception

提问by gleng

I have the following:

我有以下几点:

string outOfRange = "2147483648"; // +1 over int.MaxValue

Obviously if you have anything other than a number this will fail:

显然,如果您有数字以外的任何东西,这将失败:

var defaultValue = 0;
int.TryParse(outOfRange, out defaultValue);

My question is, since this IS a number, and it WILL fail when you int.TryParse(), how do you tell that it failed because the string was out of the bounds of the container it's stored in?

我的问题是,由于这是一个数字,并且当您使用它时它会失败,您int.TryParse()如何判断它失败是因为字符串超出了它所存储的容器的边界?

采纳答案by Chris Sinclair

I would attempt to parse, if it fails, thenattempt to parse a higher-capacity value. If the higher capacity value passes parsing, then you know it's out of range. If it fails as well, then it's bad input.

如果失败,我会尝试解析,然后尝试解析更高容量的值。如果较高的容量值通过解析,则您知道它超出范围。如果它也失败了,那么它就是错误的输入。

string outOfRange = "2147483648"; // +1 over int.MaxValue
int result;
if (!Int32.TryParse(outOfRange, out result))
{
    long rangeChecker;
    if (Int64.TryParse(outOfRange, out rangeChecker))
        //out of range
    else
        //bad format
}

Unfortunately, I don't think there's a way to do this generically for any type; you'd have to write an implementation for all types. So for example, what do do for Int64? Maybe use BigIntegerinstead:

不幸的是,我认为没有办法对任何类型进行通用的操作;你必须为所有类型编写一个实现。例如,做什么Int64?也许BigInteger改用:

string outOfRange = "9223372036854775808"; // +1 over Int64.MaxValue
long result;
if (!Int64.TryParse(outOfRange, out result))
{
    BigInteger rangeChecker;
    if (BigInteger.TryParse(outOfRange, out rangeChecker))
        //out of range
    else
        //bad format
}

EDIT: doublefloating point values may be more fun since AFAIK, there's no "BigDecimal" and you mayhave to also account for values that approach 0 at the very extreme (not sure about that). Possibly you could do a variation on the BigIntegercheck but you might also have to account for decimal points (probably a simple regex would be best here to have only numbers, an optional negative sign, and only one at mostdecimal point). If there are any decimal points, you'd have to truncate them out and simply check the integer portion of the string.

编辑:double自 AFAIK 以来,浮点值可能更有趣,没有“BigDecimal”,您可能还必须考虑在极端情况下接近 0 的值(不确定)。可能你可以对BigInteger支票做一个变体,但你可能还需要考虑小数点(可能一个简单的正则表达式在这里最好只有数字,一个可选的负号,最多只有一个小数点)。如果有任何小数点,您必须将它们截断并简单地检查字符串的整数部分。

EDITx2: Here's a pretty ugly implementation for checking doublevalues too:

EDITx2:这也是检查double值的一个非常丑陋的实现:

// +bajillion over Double.MaxValue
string outOfRange = "90000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.1";
double result;
if (!Double.TryParse(outOfRange, out result))
{
    string bigIntegerInput = outOfRange;

    if (!Regex.IsMatch(bigIntegerInput, @"^-?[0-9]\d*(\.\d+)?$"))
        //bad format

    int decimalIndex = bigIntegerInput.IndexOf('.');
    if (decimalIndex > -1)
        bigIntegerInput = bigIntegerInput.Substring(0, decimalIndex);

    BigInteger rangeChecker;
    if (BigInteger.TryParse(bigIntegerInput, out rangeChecker))
        //out of range
    else
        //bad format
}

But honestly, at this point I think we've just gone off the deep end. Unless you have some real performance bottleneck, or your application has out-of-range values inputted frequently, you might be better off just catching them the odd time it happens as in this answeror perhaps more simply, applying a regexto the input. In my last example, I may have as well just quit after doing the regex anyway (but I don't know off the top of my head if the TryParseimplementations are more lenient, allowing for exponential/scientific notation. If so, the regex would have to cover these as well)

但老实说,在这一点上,我认为我们刚刚走到了尽头。除非您有一些真正的性能瓶颈,或者您的应用程序经常输入超出范围的值,否则您最好在这个答案中发生的奇怪时间捕获它们,或者更简单地,将正则表达式应用于输入。在我的最后一个示例中,无论如何我也可能在执行正则表达式后退出(但我不知道TryParse实现是否更宽松,允许指数/科学记数法。如果是这样,正则表达式将也必须涵盖这些)

回答by Yoav

I'd go with the Try/Catchsolution for this scenario.

我会采用Try/Catch这种情况的解决方案。

        string outOfRange = "2147483648";
        try
        {
            int.Parse(outOfRange);
        }
        catch (OverflowException oex)
        {

        }
        catch (Exception ex)
        { }

I know that most people here would recommend avoiding this but sometimes we just have to use it (or we don't have to but it would just save us a lot of time).
here'sa little post about the efficiency of Try/Catch.

我知道这里的大多数人会建议避免这种情况,但有时我们只需要使用它(或者我们不必使用它,但这只会为我们节省大量时间)。
这里有一篇关于Try/Catch.

回答by Konstantin

can parse to decimal and then check range, avoids try/catch

可以解析为十进制然后检查范围,避免尝试/捕获

string s = "2147483648";
decimal.Parse(s) > int.MaxValue;

回答by Tim S.

You could try parsing with BigInteger.

您可以尝试使用BigInteger.

BigInteger bigInt;
bool isAnOutOfRangeInt = BigInteger.TryParse(input, out bigInt)
                         && (bigInt > int.MaxValue || bigInt < int.MinValue);
// if you care to have the value as an int:
if (!isAnOutOfRangeInt)
{
    int intValue = (int)bigInt;
}

回答by FrankPl

string outOfRange = "2147483648"; // +1 over int.MaxValue
int value;
if(! int.TryParse(outOfRange, out value)) {
    try {
        int.Parse(defaultValue);
    } catch(OverflowException e) {
        // was overflow
    } catch(Exception e) {
        // was other reason
    }
}

Assuming that there are few cases where the number is too large, the overhead of exception throwing and catching may be tolerable, as the normal cases are handled with the faster TryParsemethod without involving exceptions.

假设数量过大的情况很少,抛出和捕获异常的开销可能是可以忍受的,因为正常情况用更快的TryParse方法处理,不涉及异常。

This would work similar for other numeric data types like floats, ...

这对于其他数字数据类型(如浮点数,...

回答by Az Za

I would look at using System.Convert.ToInt32(String)as the mechanism to convert things; namely because OverflowException has already been implemented for you.

我会考虑使用System.Convert.ToInt32(String)作为转换事物的机制;即因为已经为您实现了 OverflowException。

This is convenient because you can do something simple like

这很方便,因为你可以做一些简单的事情,比如

 try 
 {
      result = Convert.ToInt32(value);
      Console.WriteLine("Converted the {0} value '{1}' to the {2} value {3}.",
                    value.GetType().Name, value, result.GetType().Name, result);
 }
 catch (OverflowException) 
 {
      Console.WriteLine("{0} is outside the range of the Int32 type.", value);
 }   
 catch (FormatException) 
 {
      Console.WriteLine("The {0} value '{1}' is not in a recognizable format.",
                    value.GetType().Name, value);
 }   

and the logic is already a part of the standard System library.

并且逻辑已经是标准系统库的一部分。

回答by meilke

Use the normal Parseinstead of the TryParse. And then use it inside a try/catch because it will give you the appropriate exception. See this for details: http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx. The exception you are looking for is OverflowException.

使用正常Parse而不是TryParse. 然后在 try/catch 中使用它,因为它会给你适当的异常。有关详细信息,请参阅:http: //msdn.microsoft.com/en-us/library/b3h1hf19.aspx。您正在寻找的例外是OverflowException

回答by Joachim Isaksson

The straight forward way would be to instead use Int32.Parse(string s)and catch OverflowException;

直接的方法是改用Int32.Parse(string s)和 catch OverflowException

OverflowException
s represents a number less than MinValue or greater than MaxValue.

OverflowException
s 表示小于 MinValue 或大于 MaxValue 的数字。