Java 如何检测 32 位 int 上的整数溢出?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21233582/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I detect integer overflow on 32 bits int?
提问by ashur
I know such topic was asked several times, but my question is about overflow on full 32 bits of int. For example:
我知道这样的话题被问过几次,但我的问题是关于 int 的完整 32 位溢出。例如:
11111111111111111111111111111111 +
00000000000000000000000000000001 =
00000000000000000000000000000000 //overflow!
I found topicwith similar question about this, however the algorithm is not perfect.
我发现了与此相关的类似问题的主题,但是该算法并不完美。
11111111111111111111111111111111 +
00000000000000000000000000000000 =
00000000000000000000000000000000 //overflow!
Is there any simple, fast, safer way to check this ?
有没有简单、快速、更安全的方法来检查这个?
采纳答案by Patryk Czarnik
Math.addExact
throws exception on overflow
Math.addExact
溢出时抛出异常
Since Java 8 there is a set of methods in the Math
class:
从 Java 8 开始,Math
类中有一组方法:
…and versions for long as well.
......还有很长的版本。
Each of these methods throws ArithmeticException
if overflow happens. Otherwise they return the proper result if it fits within the range.
ArithmeticException
如果发生溢出,这些方法中的每一个都会抛出。否则,如果它适合范围内,它们将返回正确的结果。
Example of addition:
添加示例:
int x = 2_000_000_000;
int y = 1_000_000_000;
try {
int result = Math.addExact(x, y);
System.out.println("The proper result is " + result);
} catch(ArithmeticException e) {
System.out.println("Sorry, " + e);
}
See this code run live at IdeOne.com.
Sorry, java.lang.ArithmeticException: integer overflow
抱歉,java.lang.ArithmeticException:整数溢出
回答by Tim B
long test = (long)x+y;
if (test > Integer.MAX_VALUE || test < Integer.MIN_VALUE)
// Overflow!
回答by Durandal
Overflow can be detected by a logical expression of the most significant bit of the two operands and the (truncated) result (I took the logical expression from the MC68030 manual):
溢出可以通过两个操作数的最高有效位的逻辑表达式和(截断的)结果来检测(我从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;
}
回答by GOTO 0
The most intuitive method I can think of: calculate the sum (or difference) as a long
, then convert that sum to an int
and see if its value has changed.
我能想到的最直观的方法是:将总和(或差)计算为 a long
,然后将该总和转换为 anint
并查看其值是否已更改。
long longSum = (long) a + b;
int sum = (int) longSum;
if (sum == longSum) {
// sum contains the correct result
} else {
// overflow/underflow
}
Remember that on modern 64 bit processors, working with long
s is no less efficient than working with int
s (the opposite may be true). So if you have a choice between checking for overflows or using long
s, go for the latter.
请记住,在现代 64 位处理器上,使用long
s 并不比使用int
s效率低(反之亦然)。因此,如果您可以在检查溢出或使用long
s之间做出选择,请选择后者。
回答by Vusal
Try this way:
试试这个方法:
boolean isOverflow(int left, int right) {
return right > 0
? Integer.MAX_VALUE - right < left
: Integer.MIN_VALUE - right > left;
}
From: https://wiki.sei.cmu.edu/confluence/display/java/NUM00-J.+Detect+or+prevent+integer+overflow
来自:https: //wiki.sei.cmu.edu/confluence/display/java/NUM00-J.+Detect+or+prevent+integer+overflow