How Does Java Handle Integer Underflows and Overflows and How Would You Check For It

How does Java handle integer underflows and overflows and how would you check for it?

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 as follows:

public static boolean willAdditionOverflow(int left, int right) {
if (right < 0 && right != Integer.MIN_VALUE) {
return willSubtractionOverflow(left, -right);
} else {
return (~(left ^ right) & (left ^ (left + right))) < 0;
}
}

public static boolean willSubtractionOverflow(int left, int right) {
if (right < 0) {
return willAdditionOverflow(left, -right);
} else {
return ((left ^ right) & (left ^ (left - right))) < 0;
}
}

(you can substitute int by long to perform the same checks for long)

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.


If you happen to be on Java8 already, then you can make use of the new Math#addExact() and Math#subtractExact() methods which will throw an ArithmeticException on overflow.

public static boolean willAdditionOverflow(int left, int right) {
try {
Math.addExact(left, right);
return false;
} catch (ArithmeticException e) {
return true;
}
}

public static boolean willSubtractionOverflow(int left, int right) {
try {
Math.subtractExact(left, right);
return false;
} catch (ArithmeticException e) {
return true;
}
}

The source code can be found here and here respectively.

Of course, you could also just use them right away instead of hiding them in a boolean utility method.

How to detect and prevent integer overflow when multiplying an integer by float in Java?

Below is a C approach that may shed light in Java.

Perform the multiplication using double, not float math before the assginment to gain the extra precision/range of double. Overflow is not then expected.

A compare like c > Integer.MAX_VALUE suffers from Integer.MAX_VALUE first being converted into a double. This may lose precision.*1 Consider what happens if the converted value is Integer.MAX_VALUE + 1.0. Then if c is Integer.MAX_VALUE + 1.0, code will attempt to return (int) (Integer.MAX_VALUE + 1.0) - not good. Better to use well formed limits. (Negative ones too.) In C, maybe Java, floating point conversion to int truncates the fraction. Special care is needed near the edges.

#define INT_MAX_PLUS1_AS_DOUBLE ((INT_MAX/2 + 1)*2.0)

int mulInt(int a, float b) {
// double c = a * b;
double c = (double) a * b;

//return c > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)c;
if (c < INT_MAX_PLUS1_AS_DOUBLE && c - INT_MIN > -1.0) {
return (int) c;
}
if (c > 0) return INT_MAX;
if (c < 0) return INT_MIN;
return 0; // `b` was a NaN
}

c - INT_MIN > -1 is like c > INT_MIN - 1, but as INT_MIN is a -power-of-2, INT_MIN - 1 might not convert precisely to double. c - INT_MIN is expected to be exact near the edge cases.


*1 When int is 32-bit (or less) and double is 64-bit (with 53-bit significant) not an issue. But important with wider integer types.

How to prevent integer overflow in Java code?

It is a difficult problem from an engineering perspective.

The Secure Coding site recommends:

  • use of preconditions; i.e. range-check the inputs so that overflow is impossible,
  • doing each individual arithmetic operation using the next larger primitive integer type and explicitly checking for overflow, or
  • using BigInteger.

This Dr Dobbs article suggests creating a library of primitive arithmetic methods that do each primitive operation with an explicit overflow check. (You could view this as an implementation of bullet point #2 above.) But the authors go further by suggesting that you use bytecode rewriting to replace arithmetic bytecodes with calls to the equivalent methods which incorporate overflow checks.

Unfortunately, there is no way to enable overflow checking natively in Java. (But the same applies in lots of other languages; e.g. C, C++ ... )

How Java handle integer underflows and overflows?

Underflow is the exact opposite of overflow.

int high = Integer.MAX_VALUE;
int overflow = high + 1;

int low = Integer.MIN_VALUE;
int underflow = low - 1;

And you handle it the same way: you make sure inputs are not going to put yourself in the range of over/underflow, and make the user aware of potential shortcomings. (Consider Math.abs(Integer.MIN_VALUE) == Integer.MIN_VALUE for instance.)

Does Javascript handle integer overflow and underflow? If yes, how?

In a simple test, when I try this:

var max = Number.MAX_VALUE;
var x = max + 10;

var min = Number.MIN_VALUE;
var y = min / 10;

I find that x and max have the same value (in Chrome, IE and Firefox) so it appears that some overflows are just pegged to the max value. And, y gets pegged to 0 so some underflows seem to go to zero.

Ahhh, but it is not quite that simple. Not all overflows go to Number.MAX_VALUE and not all underflows go to Number.MIN_VALUE. If you do this:

var max = Number.MAX_VALUE;
var z = max * 2;

Then, z will be Infinity.

It turns out that it depends upon how far you overflow/underflow. If you go too far, you will get INFINITY instead. This is because of the use of IEEE 754 round-to-nearest mode where the max value can be considered nearer than infinity. See Adding to Number.MAX_VALUE for more detail. Per that answer, values of 1.7976931348623158 × 10308 or greater round to infinity. Values between Number.MAX_VALUE and that will round to Number.MAX_VALUE.

To, make things even more complicated, there is also something as gradual underflow which Javascript supports. This is where the mantissa of the floating point value has leading zeroes in it. Gradual underflow allows floating point to represent some smaller numbers that it could not represent without that, but they are represented at a reduced precision.

You can see exactly where the limits are:

>>> Number.MAX_VALUE + 9.979201e291
1.7976931348623157e+308
>>> Number.MAX_VALUE + 9.979202e291
Infinity

Here's a runnable snippet you can try in any browser:

var max = Number.MAX_VALUE;var x = max + 10;
var min = Number.MIN_VALUE;var y = min / 10;
var z = max * 2;
document.getElementById("max").innerHTML = max;document.getElementById("max10").innerHTML = x;document.getElementById("min").innerHTML = min;document.getElementById("min10").innerHTML = y;document.getElementById("times2").innerHTML = z;
body {    font-family: "Courier New";     white-space:nowrap;}
Number.MAX_VALUE      = <span id="max"></span><br>Number.MAX_VALUE + 10 = <span id="max10"></span><br><br>Number.MIN_VALUE      = <span id="min"></span><br>Number.MIN_VALUE / 10 = <span id="min10"></span><br>  <br>Number.MAX_VALUE * 2  = <span id="times2"></span><br>

how to overcome problem in integer overflow even using long also wrong answers?

sum=(arr[a-1])*(arr[a-2]); 

This multiples an int by an int and then assigns the int result (which may have overflowed) to a long variable.

To use long arithmetic, write

sum = (long) arr[a-1] * (long) arr[a-2]; 

You don't need both casts, but is seems a lttle clearer with them.

Integer overflow during modulo division

Haven't done Java for a while, but this seems language agnostic (and not related to modulo): You are using an int (prod), the other solution uses a long (ways).

The multiplication of your variable (either prod or ways) with j (here 12) is what overflows. 479001600 * 12 is 5,748,019,200. If both arguments are an int this will overflow. The largest 32bit value is 4,294,967,295.

If one side of the expression is a long, the result will be a long instead -> No overflow.



Related Topics



Leave a reply



Submit