Math.abs() returns the absolute value of an int, long, float or double, while Math.absExact() does the same for int and long but throws an ArithmeticException when the result does not fit in the type. The only inputs where the two methods differ are Integer.MIN_VALUE and Long.MIN_VALUE, for which Math.abs() returns the negative input unchanged.
We use absolute values for distances, differences between two readings, tolerances in comparisons and array indexes derived from hash codes. Math.absExact(), added in Java 15, is the choice when the input can come from outside and a negative “absolute value” would corrupt the result.
The following example compares both methods on a normal value and on the boundary value.
int distance = Math.abs(-15); // 15
double depth = Math.abs(-10.56); // 10.56
int broken = Math.abs(Integer.MIN_VALUE); // -2147483648
int safe = Math.absExact(-15); // 15
int checked = Math.absExact(Integer.MIN_VALUE); // ArithmeticException: Overflow to represent absolute value of Integer.MIN_VALUE
Notice the third line, where Math.abs() returns a negative number without any error. We look at what an absolute value is, the overloads of Math.abs(), why Integer.MIN_VALUE overflows, how absExact() detects it, and a real bug caused by Math.abs() on a hash code.
1. What Is an Absolute Value?
The absolute value of a number, written |x|, is the number without its sign. In other words, it is the distance of the number from zero on the number line, so it is never negative.
- |5| = 5, because 5 is already positive.
- |-8| = 8, because -8 is 8 steps away from zero.
- |0| = 0.
Absolute values are common wherever only the size of a value matters, not its direction. A depth gauge on a dive computer shows 30 meters whether the reading is stored as -30 or 30, and a step counter that compares two GPS altitudes needs the size of the change, not whether the walker went up or down.
2. Java Math.abs() Function
The Math.abs() method returns the absolute value of its argument. It has four overloads, one for each numeric type that Java arithmetic works with, and each returns the same type it receives.
| Overload | Example call | Result |
|---|---|---|
| static int abs(int a) | Math.abs(-15) | 15 |
| static long abs(long a) | Math.abs(-123456789L) | 123456789 |
| static float abs(float a) | Math.abs(-7.8f) | 7.8 |
| static double abs(double a) | Math.abs(-10.56) | 10.56 |
The byte, short and char types have no overload of their own. Java widens them to int before the call, so Math.abs() on a byte value of -128 returns the int 128.
double doubleValue = Math.abs(-10.56); // 10.56
float floatValue = Math.abs(-7.8f); // 7.8
int intValue = Math.abs(-15); // 15
long longValue = Math.abs(-123456789L); // 123456789
byte small = -128;
int widened = Math.abs(small); // 128
For float and double, the method follows the IEEE 754 rules for the special values. It clears the sign bit, so negative zero becomes positive zero, and it never throws.
| Argument | Math.abs() result |
|---|---|
| -0.0 | 0.0 |
| Double.NEGATIVE_INFINITY | Infinity |
| Double.NaN | NaN |
double negativeZero = Math.abs(-0.0); // 0.0
double infinity = Math.abs(Double.NEGATIVE_INFINITY); // Infinity
double notANumber = Math.abs(Double.NaN); // NaN
3. The Overflow Problem With Math.abs()
Java stores int and long values in two’s complement form, which gives one more negative value than positive values. The int range goes from -2,147,483,648 to 2,147,483,647, so the absolute value of Integer.MIN_VALUE would be 2,147,483,648, one more than Integer.MAX_VALUE.

Math.abs() negates a negative argument. Negating Integer.MIN_VALUE overflows, and Java integer negation does not report overflow, so the result wraps around to Integer.MIN_VALUE itself. The same happens for Long.MIN_VALUE.
int intMinValue = Integer.MIN_VALUE;
long longMinValue = Long.MIN_VALUE;
int absInt = Math.abs(intMinValue); // -2147483648
long absLong = Math.abs(longMinValue); // -9223372036854775808
An absolute value should never be negative, yet Math.abs() returns a negative number for Integer.MIN_VALUE and Long.MIN_VALUE without throwing. The call itself is where the overflow happens, and code that relies on a non-negative result, such as an array index, fails later and far away from the cause.
The same wrap-around also hides inside expressions. Math.abs(a – b) looks like a safe distance, but if a – b overflows first, Math.abs() receives a wrong value and returns a wrong positive number that looks plausible.
int high = Integer.MAX_VALUE;
int low = -10;
int wrongGap = Math.abs(high - low); // 2147483639
long rightGap = Math.abs((long) high - low); // 2147483657
4. Detecting Overflow With Math.absExact()
Starting with JDK 15, the Math class has two absExact() methods, one for int and one for long. If the mathematical absolute value does not fit in the type, these methods throw an ArithmeticException instead of returning a misleading result. StrictMath got the same two methods in the same release.
The two signatures are static int absExact(int a) and static long absExact(long a). Let us run the previous boundary values through absExact(). The exception message names the constant that caused it, which helps when it shows up in a log.
int fine = Math.absExact(-2_000_000_000); // 2000000000
int intFails = Math.absExact(Integer.MIN_VALUE); // ArithmeticException: Overflow to represent absolute value of Integer.MIN_VALUE
long longFails = Math.absExact(Long.MIN_VALUE); // ArithmeticException: Overflow to represent absolute value of Long.MIN_VALUE
For every input other than the two minimum values, Math.abs() and Math.absExact() return the same result. The exact version does not prevent overflow, it detects it, so the caller still decides what to do, for example reject the input or switch to long or BigInteger.
static long distanceOrReject(int position) {
try {
return Math.absExact(position);
} catch (ArithmeticException e) {
throw new IllegalArgumentException("Position out of range: " + position, e);
}
}
There is no absExact() for float or double, because floating-point negation never overflows. The negative and positive ranges of double are symmetric, and values beyond the range become infinity.
5. Math.abs() vs Math.absExact()
Both methods live in java.lang.Math and cost about the same, since absExact() adds one comparison. The difference is only in what they do with the minimum value and which types they accept.
| Math.abs() | Math.absExact() | |
|---|---|---|
| Since | Java 1.0 | Java 15 |
| Types | int, long, float, double | int, long |
| Integer.MIN_VALUE | Returns -2147483648 | Throws ArithmeticException |
| Long.MIN_VALUE | Returns -9223372036854775808 | Throws ArithmeticException |
| All other values | Absolute value | Absolute value |
| Use when | Floating-point values, or the input cannot be the minimum value | Integer input from users, files or hash codes |
Other ways to get a safe absolute value work for different situations.
- Widening to long before the call, as in Math.abs((long) value), always works for int input because the long range is wide enough.
- BigInteger.abs() and BigDecimal.abs() never overflow, so they suit values of any size.
- Math.negateExact() throws for the minimum value too, if the code needs negation rather than an absolute value.
long widenedAbs = Math.abs((long) Integer.MIN_VALUE); // 2147483648
BigInteger bigAbs = BigInteger.valueOf(Long.MIN_VALUE).abs(); // 9223372036854775808
int negated = Math.negateExact(Integer.MIN_VALUE); // ArithmeticException: integer overflow
6. A Real Bug With Math.abs() on a hashCode()
A cache splits its entries into 10 segments, and each key goes to segment Math.abs(key.hashCode()) % 10. The code works in testing for months, until a key arrives whose hashCode() is Integer.MIN_VALUE. The string “polygenelubricants” is a well-known example of such a key.
int hash = "polygenelubricants".hashCode(); // -2147483648
int badSegment = Math.abs(hash) % 10; // -8
Using -8 as an array index throws an ArrayIndexOutOfBoundsException, and only for that one key. The safe version uses Math.floorMod(), which always returns a value between 0 and the divisor minus one, or clears the sign bit with & 0x7fffffff.
int keyHash = "polygenelubricants".hashCode(); // -2147483648
int segment = Math.floorMod(keyHash, 10); // 2
int masked = (keyHash & 0x7fffffff) % 10; // 0
Math.absExact(hash) % 10 would also avoid the bad index, but it throws for that key, so the cache would reject a valid key. For index calculations, Math.floorMod() is the right tool, and Math.absExact() is the right tool when a minimum value means the input is wrong.
7. absExact() Before Java 15
Code that still runs on Java 11 or earlier can add the same check by hand. The method compares the argument with the minimum value and delegates to Math.abs() for everything else.
static int absExactLegacy(int a) {
if (a == Integer.MIN_VALUE) {
throw new ArithmeticException("Overflow to represent absolute value of Integer.MIN_VALUE");
}
return Math.abs(a);
}
int legacyResult = absExactLegacy(-42); // 42
int legacyFails = absExactLegacy(Integer.MIN_VALUE); // ArithmeticException: Overflow to represent absolute value of Integer.MIN_VALUE
Since Java 15 we use the built-in method, because the name tells every reader what the check is for and the message is the same in every project. The same family of exact arithmetic methods covers addition, subtraction and multiplication, and Math.divideExact() covers division.
8. Math.abs() and absExact() FAQs
The one negative result of Math.abs() surprises developers who expect an absolute value to be non-negative in every case.
8.1. Why does Math.abs() return a negative number?
Only for Integer.MIN_VALUE and Long.MIN_VALUE. Their positive counterparts are one larger than the maximum value, so the negation wraps around and the method returns the input unchanged.
8.2. Is there an absExact() for double?
No. Floating-point negation never overflows, so Math.abs(double) is always correct. It returns positive zero for -0.0, positive infinity for both infinities and NaN for NaN.
8.3. How do we get the absolute value without Math.abs()?
A conditional expression such as value < 0 ? -value : value works, but it has the same overflow for the minimum value. It adds nothing over Math.abs(), so we keep the library call.
int value = -25;
int manual = value < 0 ? -value : value; // 25
8.4. Which Java version added Math.absExact()?
Java 15, through JDK-8241805. The methods exist for int and long in both Math and StrictMath.
8.5. Should we replace every Math.abs() call with absExact()?
No. Replace the calls whose integer input can reach the minimum value, such as hash codes, differences of large numbers or values parsed from external data. For float and double, and for small values such as dice rolls, Math.abs() stays the right call.
9. Conclusion
Math.abs() returns the absolute value for all four numeric types, but for Integer.MIN_VALUE and Long.MIN_VALUE it returns the negative input because the positive value does not fit. Math.absExact(), available since Java 15 for int and long, throws an ArithmeticException for those values instead.
We use absExact() when an overflow means bad input, Math.floorMod() for index calculations from hash codes, and widening to long or BigInteger when the full value is needed. More numeric basics are part of the Java tutorial.
10. References
- Math.abs() Javadoc (Java 25)
- Math.absExact() Javadoc
- JLS 4.2.1, Integral Types and Values
- JLS 15.15.4, Unary Minus Operator
- JDK-8241805, add Math.absExact
Happy Learning !!