Java 8 – Math Exact examples
Java 8 introduced new methods in the Math
class that will throw an ArithmeticException
to handle overflows. These methods consist of addExact
, substractExact
, multiplyExact
, incrementExact
, decrementExact
and negateExact
with int
and long
arguments. In addition, there’s a static toIntExact
method to convert a long
value to an int
that also throws ArithmeticException
.
Before Java 8 the programmer had to manually debug to find the variables in the code that overflow. I was quite excited to find out that Java 8 introduced a new set of methods that throw an exception when the result overflows. For many developers this change doesn’t have a major effect, but for humble developers like myself, it will certainly affect the time spent scratching our heads to understand why the result is wrong or having to take complicated precautions to dodge an overflow.
1. Math.multiplyExact
This example demonstrates the difference between common multiplication and the new multiplyExact
package com.mkyong.exactmethods;
package com.mkyong;
public class MultiplyExact {
public static void main(String[] args) {
int x = Integer.MAX_VALUE; //( = 2 147 483 647)
int y = Integer.MAX_VALUE;
Object z;
System.out.println("---Before Java 8---");
z = x * y;
System.out.println("z : " + z);
System.out.println("\n---Since Java 8---");
try {
z = Math.multiplyExact(x, y);
} catch (ArithmeticException e) {
System.out.println(e.getMessage()); //Java 8 throws integer overflow
z = Math.multiplyExact((long) x, (long) y);
System.out.println("z : " + z);
}
if (z instanceof Long) {
System.out.println("\n> yuuuup z is Long");
}
}
}
Output:
---Before Java 8---
z : 1
---Since Java 8---
integer overflow
z : 4611686014132420609
> yuuuup z is Long
2. Detect and handle the overflow
An example where we handle the overflow for integer
and determine the overflow for long
.
package com.mkyong.exactmethods;
public class MultiplyExact2 {
public static void main(String[] args) {
int x = 1000000;
int y = 1000000;
long a = Long.MAX_VALUE; //( = 9 223 372 036 854 775 807)
long b = Long.MAX_VALUE;
Object z, c;
System.out.println("---Before Java 8---");
z = x * y;
c = a * b;
System.out.println("z : " + z);
System.out.println("c : " + c);
System.out.println("\n---Since Java 8---");
try {
z = Math.multiplyExact(x, y);
c = Math.multiplyExact(a, b);
} catch (ArithmeticException e) {
try {
z = Math.multiplyExact((long) x, (long) y);
c = null;
} catch (ArithmeticException ex) {
z = null;
}
}
if (z instanceof Integer) {
System.out.println("z is instance of Integer: " + z);
}
if (z instanceof Long) {
System.out.println("z is instance of Long: " + z);
} else {
System.out.println("Overflow for z");
}
if (c instanceof Integer) {
System.out.println("Instance of Integer: " + c);
}
if (c instanceof Long) {
System.out.println("Instance of Long: " + c);
} else {
System.out.println("Overflow for c");
}
}
}
Output:
---Before Java 8---
z : -727379968
c : 1
---Since Java 8---
z is instance of Long: 1000000000000
Overflow for c
3. All xxxExact methods
An example demonstrating all the new xxxExact
methods
package com.mkyong.exactmethods;
public class AllExactMethods {
public static void main(String[] args){
int x = 10000;
int y = 10000;
Object z;
z = Math.addExact(x, y);
System.out.println("addExact: " + x + " + " + y + " = " + z);
z = Math.subtractExact(x, y);
System.out.println("subtractExact: " + x + " - " + y + " = " + z);
z = Math.multiplyExact(x, y);
System.out.println("multiplyExact: " + x + " * " + y + " = " + z);
z = Math.incrementExact(x);
System.out.println("incrementExact: " + x + " + 1 = " + z);
z = Math.decrementExact(y);
System.out.println("decrementExact: " + y + " - 1 = " + z);
z = Math.negateExact(x);
System.out.println("negateExact: " + x + " * -1 = " + z);
}
}
Output:
addExact: 10000 + 10000 = 20000
subtractExact: 10000 - 10000 = 0
multiplyExact: 10000 * 10000 = 100000000
incrementExact: 10000 + 1 = 10001
decrementExact: 10000 - 1 = 9999
negateExact: 10000 * -1 = -10000