如何检查在Java中相乘两个数字是否会导致溢出?

2022-08-31 09:16:13

我想处理将两个数字相乘导致溢出的特殊情况。代码如下所示:

int a = 20;
long b = 30;

// if a or b are big enough, this result will silently overflow
long c = a * b;

这是一个简化的版本。在实际程序中,并在运行时从其他位置获取。我想实现的是这样的:ab

long c;
if (a * b will overflow) {
    c = Long.MAX_VALUE;
} else {
    c = a * b;
}

你如何建议我最好地编写这个代码?

更新:并且在我的场景中始终是非负的。ab


答案 1

Java 8 有 ,等等 int 和 long.这些会引发未经检查的溢出。Math.multiplyExactMath.addExactArithmeticException


答案 2

如果 和 均为正,则可以使用:ab

if (a != 0 && b > Long.MAX_VALUE / a) {
    // Overflow
}

如果您需要同时处理正数和负数,那么它更复杂:

long maximum = Long.signum(a) == Long.signum(b) ? Long.MAX_VALUE : Long.MIN_VALUE;

if (a != 0 && (b > 0 && b > maximum / a ||
               b < 0 && b < maximum / a))
{
    // Overflow
}

这是我用来检查这个的小桌子,假装溢出发生在-10或+10:

a =  5   b =  2     2 >  10 /  5
a =  2   b =  5     5 >  10 /  2
a = -5   b =  2     2 > -10 / -5
a = -2   b =  5     5 > -10 / -2
a =  5   b = -2    -2 < -10 /  5
a =  2   b = -5    -5 < -10 /  2
a = -5   b = -2    -2 <  10 / -5
a = -2   b = -5    -5 <  10 / -2