如何以高效的方式检查乘法中的溢出?

时间:2013-07-01 01:04:07

标签: java math overflow

让我说我有:

int result = value1 * value2;
boolean isOverflow = ?

如何以高效的方式检查溢出?我找到了this solution but it seems pretty expensive。我也注意到this other SO question但是没有可用的答案......

更新:无法保证这些值是正数还是负数。

2 个答案:

答案 0 :(得分:4)

您可以使用checkedMultiply包中LongMath类提供的com.google.common.math。 有关信息,请查看java docs

来自Java 8类的multiplyExact Math方法。对于java文档,请单击here

您可以通过以下方式检查溢出 -

long overflowCheck;
if(Math.sign(value1) == Math.sign(value2)) {
   overflowCheck = Long.MAX_VALUE 
} else {
  overflowCheck = Long.MIN_VALUE;
}

if (value1 != 0 && (value2 > 0 && value2 > overflowCheck / value1 ||
    value2 < 0 && value2 < overflowCheck / value1))
{
   isOverflow = true; 
}

答案 1 :(得分:2)

好消息是,在新的JDK 8中,在Math类中会有一些方法来执行抛出溢出异常的操作。

例如,当发生溢出时,新的Math.multiplyExact方法抛出ArithmeticException。也许一个好方法是通过复制这个确切的实现,如果你正在使用以前版本的Java,那么以后,当你升级到JDK 8时,你所要做的就是使用新的JDK实现对于方法。

JDK 8中的当前实现如下:

/**
  * Returns the product of the arguments,
  * throwing an exception if the result overflows an {@code int}.
  *
  * @param x the first value
  * @param y the second value
  * @return the result
  * @throws ArithmeticException if the result overflows an int
  * @since 1.8
  */
public static int multiplyExact(int x, int y) {
    long r = (long)x * (long)y;
    if ((int)r != r) {
       throw new ArithmeticException("long overflow");
    }
    return (int)r;
 }