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
How to Convert a Byte Array to a Hex String in Java
Stringbuilder VS String Concatenation in Tostring() in Java
Providing White Space in a Swing Gui
What Is Pecs (Producer Extends Consumer Super)
Validating Input Using Java.Util.Scanner
When Do You Use Java'S @Override Annotation and Why
How to Import the Javax.Servlet/Jakarta.Servlet API in My Eclipse Project
How to Read/Convert an Inputstream into a String in Java
Non-Static Variable Cannot Be Referenced from a Static Context
How to Create a Generic Array in Java
How to Add Local Jar Files to a Maven Project
When to Use Linkedlist Over Arraylist in Java
Gui Not Working After Rewriting to MVC
How to Simulate the C++ 'Friend' Concept in Java
When Is the Finalize() Method Called in Java
What Are the Differences Between a Hashmap and a Hashtable in Java