Gil*_*ili 17 java double integer-overflow bigdecimal
Java 8为我们提供了Math.addExact(),但不是小数.
是否有可能double和BigDecimal溢出?通过Double.MAX_VALUE和如何获得最大的BigDecimal值判断我会说答案是肯定的.
因此,为什么我们不也Math.addExact()为这些类型?什么是最可维护的方式来检查这个?
dur*_*597 13
double溢出到Infinity和-Infinity,它不绕回.BigDecimal不会溢出,期间,它仅受计算机内存量的限制.请参阅:如何获得最大的BigDecimal值
+和之间的唯一区别.addExact是它尝试检测是否发生溢出并抛出异常而不是换行.这是源代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
如果你想检查是否发生了溢出,从某种意义上说,double无论如何都可以更简单地进行,因为你可以简单地检查Double.POSITIVE_INFINITY或Double.NEGATIVE_INFINITY; 在的情况下,int和long,这是一个稍微复杂的问题,因为它并不总是一个固定值,而在另一个,这可能是输入(例如Infinity + 10 = Infinity,你可能不希望扔在这种情况下的例外).
由于所有这些原因(我们甚至还没有提到NaN),这可能addExact是JDK中不存在这种方法的原因.当然,您始终可以将自己的实现添加到自己的应用程序中的实用程序类中.
您不需要addExact浮点数字函数的原因是因为它不是环绕,而是溢出到Double.Infinity.
因此,您可以在操作结束时非常轻松地检查它是否溢出。由于Double.POSITIVE_INFINITY + Double.NEGATIVE_INFINITY是 NaN,您还必须在更复杂的表达式的情况下检查 NaN。
这不仅更快,而且更容易阅读。您不必 Math.addExact(Math.addExact(x, y), z)将 3 个双打加在一起,而是可以这样写:
double result = x + y + z;
if (Double.isInfinite(result) || Double.isNan(result)) throw ArithmeticException("overflow");
Run Code Online (Sandbox Code Playgroud)
BigDecimal在另一方面会确实溢出,并抛出相应的异常在这种情况下,以及-这是不太可能不会发生在实践中虽然。