Tell me if the line in double / float / int / short / byte is out of range

I have the following:

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

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

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

My question is that this is an IS number and it will fail when you int.TryParse() , how do you say that it failed because the line was outside the bounds of the container in which it was stored?

+6
source share
8 answers

I would try to analyze if it does not work, then try to analyze the value of a larger capacity. If the value of the larger capacity is parsed, then you know that it is out of range. If this fails, then this is a 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 do not think there is a way to do this in the general case for any type; you will have to write an implementation for all types. So, for example, what to do for Int64 ? Perhaps 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 interesting with AFAIK, there is no "BigDecimal" there, and you may also have to consider values ​​that approach 0 in a pinch (not sure about that). You might be able to make a variation in the BigInteger test, but you might also need to consider decimal points (perhaps a simple regular expression would be best to have only numbers, an optional negative sign, and only one at most decimal point). If there are decimal points, you should truncate them and just check the whole part of the string.

EDITx2: here's a pretty ugly implementation for checking double values:

 // +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 the moment, I think we have just left the deep end. If you have some kind of real performance bottleneck, or your application has frequently used values ​​out of range, you might be better off catching them at odd times, as is the case in this answer, or perhaps more simply by applying regular expression to the input. In my last example, maybe I just left after the regex was executed (but I don’t know, from my point of view, if the TryParse implementation is softer, which allows using exponential / scientific notation, the regex should also cover them)

+2
source

I would go with a Try/Catch solution for this scenario.

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

I know that most people here recommend avoiding this, but sometimes we just need to use it (or we don't need it, but it just saves us a lot of time).
here is a short article on Try/Catch performance.

+4
source

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

 string s = "2147483648"; decimal.Parse(s) > int.MaxValue; 
+3
source
 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 cases where the number is too large, the overhead of TryParse exception trap may be acceptable, since normal cases are handled using the faster TryParse method without involving exceptions.

This will work similarly for other numeric data types such as float, ...

+2
source

You can try to parse 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; } 
+2
source

Use regular Parse instead of TryParse . And then use it inside try / catch, because it will give you the corresponding exception. See This for details: http://msdn.microsoft.com/en-us/library/b3h1hf19.aspx . The exception you are looking for is an OverflowException .

+1
source

I would like to use System.Convert.ToInt32 (String) as a mechanism for converting things; namely because OverflowException is already implemented for you.

This is convenient because you can do something simple, for example

  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 logic is already part of the standard system library.

+1
source

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

Overflowexception
s is a number less than MinValue or greater than MaxValue.

0
source

Source: https://habr.com/ru/post/952780/


All Articles