Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/325.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何检测32位int上的整数溢出?_Java_Integer_Bit Manipulation_Integer Overflow_Integer Arithmetic - Fatal编程技术网

Java 如何检测32位int上的整数溢出?

Java 如何检测32位int上的整数溢出?,java,integer,bit-manipulation,integer-overflow,integer-arithmetic,Java,Integer,Bit Manipulation,Integer Overflow,Integer Arithmetic,我知道这样的话题被问了好几次,但我的问题是关于整型32位的溢出。例如: 11111111111111111111111111111111 + 00000000000000000000000000000001 = 00000000000000000000000000000000 //overflow! 我发现有类似的问题,但是算法并不完美 11111111111111111111111111111111 + 00000000000000000000000000000000

我知道这样的话题被问了好几次,但我的问题是关于整型32位的溢出。例如:

  11111111111111111111111111111111 +
  00000000000000000000000000000001 =
  00000000000000000000000000000000   //overflow!
我发现有类似的问题,但是算法并不完美

  11111111111111111111111111111111 +
  00000000000000000000000000000000 =
  00000000000000000000000000000000  //overflow!
有什么简单、快速、安全的方法来检查这个问题吗?

longtest=(long)x+y;
long test = (long)x+y;
if (test > Integer.MAX_VALUE || test < Integer.MIN_VALUE)
   // Overflow!
如果(测试>整数.MAX|u值|测试<整数.MIN_值) //溢出!
溢出可以通过两个操作数的最高有效位的逻辑表达式和(截断的)结果(我从MC68030手册中获取了逻辑表达式)来检测:

/**
*添加两个带溢出检测的整数(r=s+d)
*/
公共静态int add(int s,int d)抛出算术异常{
int r=s+d;
如果(((s&d&r)|(~s&d&r))<0)
抛出新的算术异常(“整数溢出加法(“+s+”,“+d+”);
返回r;
}
Math.addExact
溢出时引发异常 由于Java 8,类中有一组方法:

…以及长期的版本

如果发生溢出,这些方法都会抛出。否则,如果符合范围,则返回正确的结果

添加示例:

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);
}
看这个

抱歉,java.lang.arithmetricException:整数溢出


我能想到的最直观的方法是:将总和(或差值)计算为
long
,然后将该总和转换为
int
,查看其值是否发生了变化

long longSum = (long) a + b;
int sum = (int) longSum;
if (sum == longSum) {
    // sum contains the correct result
} else {
    // overflow/underflow
}
请记住,在现代64位处理器上,使用
long
s的效率不低于使用
int
s的效率(事实可能恰恰相反)。因此,如果您可以选择检查溢出还是使用
long
s,请选择后者。

尝试以下方法:

boolean isOverflow(int left, int right) {
    return right > 0
            ? Integer.MAX_VALUE - right < left
            : Integer.MIN_VALUE - right > left;
}
boolean isOverflow(int-left,int-right){
返回右侧>0
?整数.MAX_值-右<左
:Integer.MIN_值-右>左;
}

From:

BTW,Java int始终是32位的(无论给定JVM在什么架构上运行[):“默认情况下,int数据类型是一个32位带符号的2的补码整数,最小值为-231,最大值为231-1”().因此,这里的32位规范似乎有点不相关/没有意义。x&y是否被假定为long本身?如果它们是int,我认为这不会起作用(因为溢出在长强制转换之前不会被检测到);我对吗?你错了。x在加法之前被强制转换为long(优先级).long+int int将int转换为long,最终得到long+long。因此,整个操作以64位精度完成。啊,好的,因此强制转换优先于加法运算符。谢谢!不适用于乘法。
isOverflow中的溢出(-47483648,-100000000)未检测到
。这实际上不是溢出:)Java 8的
addExact
编码为
if(((s^r)和(d^r))<0)
boolean isOverflow(int left, int right) {
    return right > 0
            ? Integer.MAX_VALUE - right < left
            : Integer.MIN_VALUE - right > left;
}