I would attempt to parse, if it fails, then attempt 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 BigInteger
instead:
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: double
floating point values may be more fun since AFAIK, there's no "BigDecimal" and you may have to also account for values that approach 0 at the very extreme (not sure about that). Possibly you could do a variation on the BigInteger
check 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 most decimal point). If there are any decimal points, you'd have to truncate them out and simply check the integer portion of the string.
EDITx2: Here's a pretty ugly implementation for checking double
values too:
// +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 answer or perhaps more simply, applying a regex to 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 TryParse
implementations are more lenient, allowing for exponential/scientific notation. If so, the regex would have to cover these as well)