How does Java handle integer underflows and overflows?
Leading on from that, how would you check/test that this is occurring?
How does Java handle integer underflows and overflows?
Leading on from that, how would you check/test that this is occurring?
It doesn't do anything -- the under/overflow just happens.
A "-1" that is the result of a computation that overflowed is no different from the "-1" that resulted from any other information. So you can't tell via some status or by inspecting just a value whether it's overflowed.
But you can be smart about your computations in order to avoid overflow, if it matters, or at least know when it will happen. What's your situation?
If it overflows, it goes back to the minimum value and continues from there. If it underflows, it goes back to the maximum value and continues from there.
You can check that beforehand using the greater than or lesser than operators.
if (someInt + valueToAdd < someInt) {
// Overflowed!
}
if (someInt - valueToSubstract > someInt) {
// Underflowed!
}
If you think that this may occur more than often, then consider using a datatype or object which can store larger values, e.g. long
or maybe java.math.BigInteger
. The last one doesn't overflow, practically, the available JVM memory is the limit.
It wraps around.
e.g:
public class test {
public static void main(String[] args) {
int i = Integer.MAX_VALUE;
int j = Integer.MIN_VALUE;
System.out.println(i+1);
System.out.println(j-1);
}
}
prints
-2147483648
2147483647
Well, as far as primitive integer types go, Java doesnt handle Over/Underflow at all (for float and double the behaviour is different, it will flush to +/- infinity just as IEEE-754 mandates).
When adding two int's, you will get no indication when an overflow occurs. A simple method to check for overflow is to use the next bigger type to actually perform the operation and check if the result is still in range for the source type:
public int addWithOverflowCheck(int a, int b) {
// the cast of a is required, to make the + work with long precision,
// if we just added (a + b) the addition would use int precision and
// the result would be cast to long afterwards!
long result = ((long) a) + b;
if (result > Integer.MAX_VALUE) {
throw new RuntimeException("Overflow occured");
} else if (result < Integer.MIN_VALUE) {
throw new RuntimeException("Underflow occured");
}
// at this point we can safely cast back to int, we checked before
// that the value will be withing int's limits
return (int) result;
}
What you would do in place of the throw clauses, depends on your applications requirements (throw, flush to min/max or just log whatever). If you want to detect overflow on long operations, you're out of luck with primitives, use BigInteger instead.