Java 8 gave us Math.addExact() for integers but not decimals.
Is it possible for double and BigDecimal to overflow? Judging by Double.MAX_VALUE and How to get biggest BigDecimal value I'd say the answer is yes.
As such, why don't we have Math.addExact() for those types as well? What's the most maintainable way to check this ourselves?
A BigDecimal is an exact way of representing numbers. A Double has a certain precision. Working with doubles of various magnitudes (say d1=1000.0 and d2=0.001 ) could result in the 0.001 being dropped alltogether when summing as the difference in magnitude is so large. With BigDecimal this would not happen.
A BigDecimal is an accurate way of expressing numbers. A Double has a reliable accuracy. Going with doubles of various magnitudes (say d1=1000.0 and d2=0.001) could occur in the 0.001 being dropped collectively when summing as the variation in magnitude is so large. With BigDecimal this would not occur.
math. BigDecimal. doubleValue() is an in-built function which converts the BigDecimal object to a double.
The limit is 32 * 2^32-1 bits for BigInteger or about 2^(4 billion).
double overflows to Infinity and -Infinity, it doesn't wrap around. BigDecimal doesn't overflow, period, it is only limited by the amount of memory in your computer. See: How to get biggest BigDecimal value
The only difference between + and .addExact is that it attempts to detect if overflow has occurred and throws an Exception instead of wraps. Here's the source code:
public static int addExact(int x, int y) {
int r = x + y;
// HD 2-12 Overflow iff both arguments have the opposite sign of the result
if (((x ^ r) & (y ^ r)) < 0) {
throw new ArithmeticException("integer overflow");
}
return r;
}
If you want to check that an overflow has occurred, in one sense it's simpler to do it with double anyway because you can simply check for Double.POSITIVE_INFINITY or Double.NEGATIVE_INFINITY; in the case of int and long, it's a slightly more complicated matter because it isn't always one fixed value, but in another, these could be inputs (e.g. Infinity + 10 = Infinity and you probably don't want to throw an exception in this case).
For all these reasons (and we haven't even mentioned NaN yet), this is probably why such an addExact method doesn't exist in the JDK. Of course, you can always add your own implementation to a utility class in your own application.
The reason you do not need a addExact function for floating point digits is because instead of wrapping around, it overflows to Double.Infinity.
Consequently you can very easily check at the end of the operation whether it overflowed or not. Since Double.POSITIVE_INFINITY + Double.NEGATIVE_INFINITY is NaN you also have to check for NaN in case of more complicated expressions.
This is not only faster but also easier to read. Instead of having Math.addExact(Math.addExact(x, y), z) to add 3 doubles together, you can instead write:
double result = x + y + z;
if (Double.isInfinite(result) || Double.isNan(result)) throw ArithmeticException("overflow");
BigDecimal on the other hand will indeed overflow and throw a corresponding exception in that case as well - this is very unlikely to ever happen in practice though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With