116. Math.clamp() and Exact Arithmetic in Java
Math.clamp() safely bounds values within a range, while Math.addExact() and multiplyExact() prevent silent integer overflow by throwing ArithmeticException.
Explanation
Two perennial source bugs in numeric Java code are: 1. Unchecked Integer Overflow: In standard Java, Integer.MAX_VALUE + 1 wraps around to Integer.MIN_VALUE silently without throwing any warning or error. If calculating financial balances or allocation buffer sizes, this wrap-around leads to catastrophic security flaws (e.g. allocating negative or tiny arrays). 2. Manual Clamping Logic: Restricting a number to [min, max] historically required awkward nested ternary expressions: Math.max(min, Math.min(val, max)), which is error-prone and inverted easily.
Java 21 introduces Math.clamp() for int, long, float, and double: Math.clamp(value, min, max) cleanly returns min if value < min, max if value > max, and value otherwise, throwing IllegalArgumentException if min > max.
For overflow protection, java.lang.Math provides the *Exact family: addExact(), subtractExact(), multiplyExact(), incrementExact(), and toIntExact(), which throw ArithmeticException upon overflow.
Example
public class MathExactAndClamp {
public static void main(String[] args) {
// 1. Math.clamp (Java 21)
int volume = 120;
int safeVolume = Math.clamp(volume, 0, 100);
System.out.println("Clamped volume: " + safeVolume); // 100
double temperature = -15.4;
double clampedTemp = Math.clamp(temperature, 0.0, 40.0);
System.out.println("Clamped temp: " + clampedTemp); // 0.0
// 2. Silent overflow vs Exact arithmetic
int max = Integer.MAX_VALUE;
int silentWrap = max + 1;
System.out.println("Silent wrap-around: " + silentWrap); // -2147483648 (DANGEROUS)
try {
Math.addExact(max, 1); // Safe!
} catch (ArithmeticException e) {
System.out.println("Caught overflow cleanly: " + e.getMessage());
}
// 3. Safe narrowing conversion
long huge = 5_000_000_000L;
try {
int downcast = Math.toIntExact(huge);
} catch (ArithmeticException e) {
System.out.println("toIntExact detected overflow on downcast: " + e.getMessage());
}
}
}Sources
- https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Math.html#clamp(long,long,long) โ Math.clamp API (Java 21)
- https://docs.oracle.com/en/java/javase/21/docs/api/java.base/java/lang/Math.html#addExact(int,int) โ Math.addExact API