双精度或大十进制溢出吗?
Java 8为我们提供了整数的Math.addExact(),但不是小数。
是否有可能溢出和溢出?通过Double.MAX_VALUE和How to get bigDecimal值来判断,我会说答案是肯定的。double
BigDecimal
因此,为什么我们没有这些类型呢?我们自己检查这个问题的最可维护方法是什么?Math.addExact()
Java 8为我们提供了整数的Math.addExact(),但不是小数。
是否有可能溢出和溢出?通过Double.MAX_VALUE和How to get bigDecimal值来判断,我会说答案是肯定的。double
BigDecimal
因此,为什么我们没有这些类型呢?我们自己检查这个问题的最可维护方法是什么?Math.addExact()
double
溢出到 和 ,它不会缠绕。 不会溢出,句号,它只受计算机内存量的限制。详见: 如何获得最大的大十进制值Infinity
-Infinity
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;
}
如果你想检查溢出是否已经发生,从某种意义上说,这样做会更简单,因为你可以简单地检查或 ;在 and 的情况下,这是一个稍微复杂一些的问题,因为它并不总是一个固定值,但在另一个固定值中,这些可能是输入(例如 在这种情况下,您可能不想引发异常)。double
Double.POSITIVE_INFINITY
Double.NEGATIVE_INFINITY
int
long
Infinity + 10 = Infinity
由于所有这些原因(我们甚至还没有提到),这可能就是为什么JDK中不存在这样的方法的原因。当然,您始终可以将自己的实现添加到自己的应用程序中的实用程序类中。NaN
addExact
您不需要浮点数字的函数的原因是,它不是环绕,而是溢出到 。addExact
Double.Infinity
因此,您可以在操作结束时非常轻松地检查它是否溢出。由于是NaN,因此在更复杂的表达式的情况下,您还必须检查NaN。Double.POSITIVE_INFINITY + Double.NEGATIVE_INFINITY
这不仅更快,而且更易于阅读。您不必将3个双精度加在一起,而是可以编写:Math.addExact(Math.addExact(x, y), z)
double result = x + y + z;
if (Double.isInfinite(result) || Double.isNan(result)) throw ArithmeticException("overflow");
BigDecimal
另一方面,在这种情况下,确实会溢出并引发相应的异常 - 这在实践中不太可能发生。