我知道这样的主题被多次询问,但我的问题是关于整个32位int 的溢出。例如:
11111111111111111111111111111111 +
00000000000000000000000000000001 =
00000000000000000000000000000000 //overflow!
我发现topic有类似的问题,但算法并不完美。
11111111111111111111111111111111 +
00000000000000000000000000000000 =
00000000000000000000000000000000 //overflow!
有没有简单快捷的方法来检查这个?
答案 0 :(得分:27)
从Java 8开始,Math类中有一组方法: toIntExact (long), addExact (int,int), subtractExact (int,int), multiplyExact (int ,int)和版本也很长。 如果发生溢出,它们会抛出ArithmeticException,如果它符合范围,它们将返回正确的结果。
添加示例:
int x = 2000000000;
int y = 1000000000;
try {
int result = Math.addExact(x, y);
System.out.println("The proper result is " + result);
} catch(ArithmeticException e) {
System.out.println("Sorry, " + e);
}
答案 1 :(得分:12)
long test = (long)x+y;
if (test > Integer.MAX_VALUE || test < Integer.MIN_VALUE)
// Overflow!
答案 2 :(得分:6)
尝试这种方式:
boolean isOverflow(int left, int right) {
return right > 0
? Integer.MAX_VALUE - right < left
: Integer.MIN_VALUE - right > left;
}
来自:https://wiki.sei.cmu.edu/confluence/display/java/NUM00-J.+Detect+or+prevent+integer+overflow
答案 3 :(得分:2)
我能想到的最直观的方法:将总和(或差异)计算为long
,然后将该总和转换为int
并查看其值是否已更改。
long longSum = (long) a + b;
int sum = (int) longSum;
if (sum == longSum) {
// sum contains the correct result
} else {
// overflow/underflow
}
请记住,在现代64位处理器上,使用long
的效率并不比使用int
s更有效(反之亦然)。因此,如果您可以选择检查溢出或使用long
,请选择后者。
答案 4 :(得分:1)
可以通过两个操作数的最高位和(截断的)结果的逻辑表达式检测溢出(我从MC68030手册中获取了逻辑表达式):
/**
* Add two int's with overflow detection (r = s + d)
*/
public static int add(int s, int d) throws ArithmeticException {
int r = s + d;
if (((s & d & ~r) | (~s & ~d & r)) < 0)
throw new ArithmeticException("int overflow add(" + s + ", " + d + ")");
return r;
}