Ste*_*eod 94 java math overflow long-integer
我想处理两个数字相乘导致溢出的特殊情况.代码看起来像这样:
int a = 20;
long b = 30;
// if a or b are big enough, this result will silently overflow
long c = a * b;
Run Code Online (Sandbox Code Playgroud)
这是一个简化版本.在真正的程序中,a并b在运行时在其他地方采购.我想要实现的是这样的:
long c;
if (a * b will overflow) {
c = Long.MAX_VALUE;
} else {
c = a * b;
}
Run Code Online (Sandbox Code Playgroud)
您如何建议我最好编码?
更新:a而且b总是在我的场景下非负.
Joh*_*ica 59
如果a并且b都是肯定的那么你可以使用:
if (a != 0 && b > Long.MAX_VALUE / a) {
// Overflow
}
Run Code Online (Sandbox Code Playgroud)
如果你需要处理正数和负数,那么它就更复杂了:
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
}
Run Code Online (Sandbox Code Playgroud)
这是一个小桌子我掀起来检查这个,假装溢出发生在-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
Run Code Online (Sandbox Code Playgroud)
rep*_*mer 17
有些Java库提供安全的算术运算,可检查长溢出/下溢.例如,番石榴的LongMath.checkedMultiply(长,长二)返回的产品a和b,只要它不溢出,并抛出ArithmeticException,如果a * b在签订溢出long运算.
您可以使用java.math.BigInteger来检查结果的大小(尚未测试代码):
BigInteger bigC = BigInteger.valueOf(a) * multiply(BigInteger.valueOf(b));
if(bigC.compareTo(BigInteger.valueOf(Long.MAX_VALUE)) > 0) {
c = Long.MAX_VALUE;
} else {
c = bigC.longValue()
}
Run Code Online (Sandbox Code Playgroud)
这是我能想到的最简单的方法
int a = 20;
long b = 30;
long c = a * b;
if(c / b == a) {
// Everything fine.....no overflow
} else {
// Overflow case, because in case of overflow "c/b" can't equal "a"
}
Run Code Online (Sandbox Code Playgroud)