可以加倍还是BigDecimal溢出?

Gil*_*ili 17 java double integer-overflow bigdecimal

Java 8为我们提供了Math.addExact(),但不是小数.

是否有可能doubleBigDecimal溢出?通过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_INFINITYDouble.NEGATIVE_INFINITY; 在的情况下,intlong,这是一个稍微复杂的问题,因为它并不总是一个固定值,而在另一个,这可能是输入(例如Infinity + 10 = Infinity,你可能不希望扔在这种情况下的例外).

由于所有这些原因(我们甚至还没有提到NaN),这可能addExact是JDK中不存在这种方法的原因.当然,您始终可以将自己的实现添加到自己的应用程序中的实用程序类中.


Voo*_*Voo 5

您不需要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在另一方面确实溢出,并抛出相应的异常在这种情况下,以及-这是不太可能不会发生在实践中虽然。

  • ...这是因为`Infinity` 上的操作是明确定义的,所以`Infinity + 除了-Infinity` 之外的任何数字仍然是`Infinity`。您可以执行任何一系列操作,如果它在中间点溢出,您将永远不会得到错误但有效的结果:它始终是无穷大之一或“NaN”。这与可能发生这种情况的整数类型形成对比。 (2认同)