Reputation: 187
How to check a number is out of the range of Integer?
If the number is greater than Integer.MAX_VALUE
, return Integer.MAX_VAlUE
If the number is less than Integer.MIN_VALUE
, return Integer.MIN_VAlUE
EX:
2000000000000 -> Integer.MAX_VALUE
This is my solution, but it seems very inefficient.
if(str.length() >= 10) {
if(str.charAt(0) != '-') {
return Integer.MAX_VALUE;
} else if(str.length() >= 11 && str.charAt(0) == '-') {
return Integer.MIN_VALUE;
}
}
Upvotes: 1
Views: 9369
Reputation: 140319
Speed-wise, your code is probably fine. The bigger problem is that it's not correct, because it's not the case that all strings with length of at least ten represent strings that exceed the range, even assuming they only contain 0-9
and -
.
To do that correctly, you'd need to compare the string to the string representations of the limits:
// Some constants.
static final String MAX_VALUE_STRING = Integer.toString(Integer.MAX_VALUE);
static final String MIN_VALUE_STRING = Integer.toString(Integer.MIN_VALUE);
static int parseClamped(String str) {
// Assuming str.matches("-?[0-9]+") is true.
if (str.startsWith("-")) {
// Negative numbers longer than MIN_VALUE.
// Obviously less than MIN_VALUE.
if (str.length() > MIN_VALUE_STRING.length()) {
return Integer.MIN_VALUE;
}
// Negative numbers of the same length as MIN_VALUE.
// Less than MIN_VALUE if it is lexicographically greater.
if (str.length() == MIN_VALUE_STRING.length() && str.compareTo(MIN_VALUE_STRING) > 0) {
return Integer.MIN_VALUE;
}
} else {
// Positive numbers longer than MAX_VALUE.
// Obviously greater than MAX_VALUE.
if (str.length() > MAX_VALUE_STRING.length()) {
return Integer.MAX_VALUE;
}
// Positive numbers of the same length as MIN_VALUE.
// Greater than MAX_VALUE if it is lexicographically greater.
if (str.length() == MAX_VALUE_STRING.length() && str.compareTo(MAX_VALUE_STRING) > 0) {
return Integer.MAX_VALUE;
}
}
return Integer.parseInt(str);
}
You could write this more concisely with a helper method:
static boolean longerThanOrAfter(String str, String c) {
return str.length() > c.length() || str.compareTo(c) > 0;
}
static int parseClamped(String str) {
// Assuming str.matches("-?[0-9]+") is true.
if (str.startsWith("-")) {
if (longerThanOrAfter(str, MIN_VALUE_STRING)) {
return Integer.MIN_VALUE;
}
} else {
if (longerThanOrAfter(str, MAX_VALUE_STRING)) {
return Integer.MAX_VALUE;
}
}
return Integer.parseInt(str);
}
This is efficient because it doesn't allocate any new objects (at least, not outside the String.compareTo
method).
But that's at the expense of lacking validation of the string. If you can't guarantee your input is numeric, you can check with a precompiled regex. That won't be terrible performance-wise, but more work is still slower than no work.
And, of course, Integer.parseInt
allows positive values to start with a +
, so you may want to consider handling that. This can be done in the same pattern, by comparing against a constant whose value is "+" + MAX_VALUE_STRING
.
Upvotes: 0
Reputation: 173
You can try to directly parse the value as int, if it's not within the Integer range, NumberFormatException will be thrown
String number = "78654567788";
try {
Integer.parseInt(number);
System.out.println("Within the range");
} catch (NumberFormatException e) {
System.out.println("out of range");
}
Upvotes: 0
Reputation: 5162
You can try the following code:
String str = "987654987855";
String max = String.valueOf(Integer.MAX_VALUE);
String min = String.valueOf(Integer.MIN_VALUE);
BigInteger b1 = new BigInteger(str);
BigInteger b_max = new BigInteger(max);
BigInteger b_min = new BigInteger(min);
boolean isOutOfRange = b1.compareTo(b_max) > 0 || b1.compareTo(b_min) < 0;
System.out.println(isOutOfRange); // Output true
Upvotes: 0
Reputation: 1342
Parse it as a long first, then check if its in range of the integer max and min.
long value = Long.parseLong(inputString);
if (value < Integer.MAX_VALUE && value > Integer.MIN_VALUE)
doWhatYouWantToDo();
Upvotes: 1