Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I check if multiplying two numbers in Java will cause an overflow?

I want to handle the special case where multiplying two numbers together causes an overflow. The code looks something like this:

int a = 20; long b = 30;  // if a or b are big enough, this result will silently overflow long c = a * b; 

That's a simplified version. In the real program a and b are sourced elsewhere at runtime. What I want to achieve is something like this:

long c; if (a * b will overflow) {     c = Long.MAX_VALUE; } else {     c = a * b; } 

How do you suggest I best code this?

Update: a and b are always non-negative in my scenario.

like image 413
Steve McLeod Avatar asked Nov 01 '09 18:11

Steve McLeod


People also ask

How do you know if a multiplication will overflow?

We have to check whether the multiplied value will exceed the 64-bit integer or not. If we multiply 100, and 200, it will not exceed, if we multiply 10000000000 and -10000000000, it will overflow.

How do you avoid overflow in multiplication in Java?

We can multiply recursively to overcome the difficulty of overflow. To multiply a*b, first calculate a*b/2 then add it twice. For calculating a*b/2 calculate a*b/4 and so on (similar to log n exponentiation algorithm).

How do you calculate overflow in Java?

To check for Integer overflow, we need to check the Integer. MAX_VALUE, which is the maximum value of an integer in Java. Let us see an example wherein integers are added and if the sum is more than the Integer. MAX_VALUE, then an exception is thrown.

How do you check for overflow in binary multiplication?

If the sum exceeds the number of bits in the integer (or unsigned) then you will have an overflow if they are multiplied together.


2 Answers

Java 8 has Math.multiplyExact, Math.addExact etc. for ints and long. These throw an unchecked ArithmeticException on overflow.

like image 103
bcoughlan Avatar answered Sep 30 '22 17:09

bcoughlan


If a and b are both positive then you can use:

if (a != 0 && b > Long.MAX_VALUE / a) {     // Overflow } 

If you need to deal with both positive and negative numbers then it's more complicated:

long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE;  if (a != 0 && (b > 0 && b > maximum / a ||                b < 0 && b < maximum / a)) {     // Overflow } 

Here's a little table I whipped up to check this, pretending that overflow happens at -10 or +10:

a =  5   b =  2     2 >  10 /  5 a =  2   b =  5     5 >  10 /  2 a = -5   b =  2     2 > -10 / -5 a = -2   b =  5     5 > -10 / -2 a =  5   b = -2    -2 < -10 /  5 a =  2   b = -5    -5 < -10 /  2 a = -5   b = -2    -2 <  10 / -5 a = -2   b = -5    -5 <  10 / -2 
like image 40
John Kugelman Avatar answered Sep 30 '22 15:09

John Kugelman