混乱关于Java中的溢出

时间:2013-10-20 22:22:42

标签: java c++ c

我有以下声明:

long result = a * b * c;

这会导致变量结果溢出。同样如此:

long result = (long)a * b * c;

但是当它被打破时,他们不会:

long result = a;
result *= b;
result *= c;

a和b的类型是int

有人可以解释为什么会这样吗?在前两种情况下,Java是否将中间结果存储在临时内部int变量中?

C和C ++的行为方式也一样吗?

2 个答案:

答案 0 :(得分:6)

假设a * b * c适合long,但a * b不适合int -

  • 您的第一个代码段会出现溢出,因为您怀疑a * b会进入临时int
  • 您声明的第二个代码段不会溢出,因为它会在每个点上乘以long个值。
  • 您的第三个代码段不会溢出,因为它也会在每个点上乘以long个值。

而且,是的,C和C ++也都这样工作;虽然取决于平台,但intlong可能会有不同的长度。

答案 1 :(得分:2)

请参阅Oracle documentation for operator precedence

一元的优先级高于乘法,因此(long)a*b*c(long)(a)*b*c

C++中相同。

我刚测试了这些程序:

public class JavaApplication2 {
    public static void main(String[] args) {
        long l = (long)Integer.MAX_VALUE;
        l *= 2;
        l *= 2;
        System.out.println(l);
    }
}

public class JavaApplication2 {
    public static void main(String[] args) {
        long l = (long)Integer.MAX_VALUE*2*2;
        System.out.println(l);
    }
}

它们显示完全相同的输出。

相比之下,删除第二个版本的演员表会出现溢出。