Java 如何处理整数下溢和上溢?
从那开始,您将如何检查/测试这种情况是否正在发生?
如果溢出,它会回到最小值并从那里继续。如果它下溢,它会回到最大值并从那里继续。
您可以按如下方式预先检查:
public static boolean willAdditionOverflow(int left, int right) { if (right < 0 && right != Integer.MIN_VALUE) { return willSubtractionOverflow(left, -right); } else { return (~(left ^ right) & (left ^ (left + right))) < 0; } } public static boolean willSubtractionOverflow(int left, int right) { if (right < 0) { return willAdditionOverflow(left, -right); } else { return ((left ^ right) & (left ^ (left - right))) < 0; } }
(您可以替换int为long对 执行相同的检查long)
int
long
如果您认为这种情况可能经常发生,那么请考虑使用可以存储更大值的数据类型或对象,例如long或可能java.math.BigInteger。最后一个不会溢出,实际上,可用的JVM内存是极限。
java.math.BigInteger
如果您碰巧已经在 Java8 上,那么您可以使用新的Math#addExact()和Math#subtractExact()方法,这将引发ArithmeticException溢出。
Math#addExact()
Math#subtractExact()
ArithmeticException
public static boolean willAdditionOverflow(int left, int right) { try { Math.addExact(left, right); return false; } catch (ArithmeticException e) { return true; } } public static boolean willSubtractionOverflow(int left, int right) { try { Math.subtractExact(left, right); return false; } catch (ArithmeticException e) { return true; } }
源代码可以分别在这里和这里找到。
当然,您也可以立即使用它们,而不是将它们隐藏在boolean实用程序方法中。
boolean