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

时间:2013-08-29 19:52:42

标签: c# wpf int tryparse outofrangeexception

我有以下内容:

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

显然,如果你有一个不是数字的东西,这将失败:

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

我的问题是,因为这是一个数字,并且当你int.TryParse()它会失败时,你怎么知道它失败了,因为字符串超出了它存储在容器的边界?

8 个答案:

答案 0 :(得分:4)

对于这种情况,我会使用Try/Catch解决方案。

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

        }
        catch (Exception ex)
        { }

我知道大多数人会建议避免这种情况,但有时我们只需要使用它(或者我们不必使用它,但它只会节省我们很多时间)。
here's关于Try/Catch的效率的一篇文章。

答案 1 :(得分:3)

可以解析为十进制,然后检查范围,避免try / catch

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

答案 2 :(得分:2)

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
    }
}

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

这与其他数字数据类型(如浮点数,......)类似。

答案 3 :(得分:2)

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

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
}

不幸的是,我认为没有办法在任何类型上做到这一点;你必须为所有类型编写一个实现。那么,例如,对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
}

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

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
}
但老实说,在这一点上,我认为我们刚刚走出了尽头。除非你有一些真正的性能瓶颈,或者你的应用程序经常输入超出范围的值,你可能最好只是在奇怪的时间捕获它们,如this answer或者更简单地说,将正则表达式应用于输入。在我的最后一个例子中,我也可以在完成正则表达式之后退出(但如果TryParse实现更宽松,我不知道我的头脑,允许指数/科学表示法。所以,正则表达式也必须涵盖这些)

答案 4 :(得分:2)

您可以尝试使用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;
}

答案 5 :(得分:1)

使用普通Parse代替TryParse。然后在try / catch中使用它,因为它会为您提供适当的异常。有关详细信息,请参阅此处:http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx。您要查找的例外是OverflowException

答案 6 :(得分:1)

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

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

 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);
 }   

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

答案 7 :(得分:0)

直接的方法是使用Int32.Parse(string s)并抓住OverflowException;

  

<强>发生OverflowException
  s表示小于MinValue或大于MaxValue的数字。