告诉双精度/foat/int/short/byte的字符串是否超出范围
本文关键字:是否 字符串 范围 short 双精度 foat int byte | 更新日期: 2023-09-27 18:29:37
我有以下内容:
string outOfRange = "2147483648"; // +1 over int.MaxValue
显然,如果你有一个数字以外的任何东西,这将失败:
var defaultValue = 0;
int.TryParse(outOfRange, out defaultValue);
我的问题是,由于这是一个数字,当你int.TryParse()
时它会失败,你如何判断它失败是因为字符串超出了它存储的容器的边界?
对于这个场景,我会选择Try/Catch
解决方案。
string outOfRange = "2147483648";
try
{
int.Parse(outOfRange);
}
catch (OverflowException oex)
{
}
catch (Exception ex)
{ }
我知道这里的大多数人都建议避免这种情况,但有时我们只需要使用它(或者我们不必使用它,但它只会节省我们很多时间)
这里有一篇关于Try/Catch
效率的小文章。
可以解析为十进制,然后检查范围,避免try/catch
string s = "2147483648";
decimal.Parse(s) > int.MaxValue;
我会尝试解析,如果失败,然后尝试解析更高容量的值。如果较高容量的值通过解析,那么您就知道它超出了范围。如果它也失败了,那么它就是糟糕的输入。
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
}
但老实说,在这一点上,我认为我们刚刚脱离了困境。除非您有一些真正的性能瓶颈,或者您的应用程序经常输入超出范围的值,否则您最好在出现这种情况时捕捉它们,如本答案所示,或者更简单地说,将正则表达式应用于输入。在我的最后一个例子中,我可能在完成正则表达式后就退出了(但我不知道TryParse
的实现是否更宽松,允许指数/科学表示法。如果是这样,正则表达式也必须涵盖这些)
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
方法处理,而不涉及异常。
这将类似于其他数字数据类型,如浮点。。。
您可以尝试使用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;
}
使用普通的Parse
而不是TryParse
。然后在try/catch中使用它,因为它会给您适当的异常。有关详细信息,请参阅:http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx.您要查找的异常是OverflowException。
我会考虑使用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);
}
并且该逻辑已经是标准系统库的一部分。
直接的方法是使用Int32.Parse(字符串s)并捕获OverflowException
;
溢出异常
s表示小于MinValue或大于MaxValue的数字。