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

gle*_*eng 8 c# wpf int tryparse outofrangeexception

我有以下内容:

string outOfRange = "2147483648"; // +1 over int.MaxValue
Run Code Online (Sandbox Code Playgroud)

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

var defaultValue = 0;
int.TryParse(outOfRange, out defaultValue);
Run Code Online (Sandbox Code Playgroud)

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

Chr*_*air 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
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,我认为没有一种方法可以对任何类型通用地执行此操作;您必须为所有类型编写一个实现。例如,做什么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
}
Run Code Online (Sandbox Code Playgroud)

编辑:double浮点值可能更有趣,因为据我所知,没有“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
}
Run Code Online (Sandbox Code Playgroud)

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