Java Puzzle读书笔记(8):表达式中隐藏的溢出

下面这段代码的输出是什么?

long lvar1 = 24 * 60 * 60 * 1000 * 1000;
long lvar2 = 24 * 60 * 60 * 1000;
System.out.println(lvar1 / lvar2);

一眼看去,应该是1000。

实际的输出是什么呢?5

为什么会得出这样奇怪的结果。我们来反汇编看一下:

执行:javap -c LongOverflowTest.class

结果可以看到:

  public static void main(java.lang.String[]);
    Code:
       0: ldc2_w        #2                  // long 500654080l
       3: lstore_1
       4: ldc2_w        #4                  // long 86400000l
       7: lstore_3

第一个表达式的结果是 500654080,与预期的结果 86400000000不同。

让我们来看看对应的二进制表示:

1010000011101110101110110000000000000
11101110101110110000000000000

是的,这里被截断了。

因为在计算时,没有指定表达式中数值的类型,所以造成都按int类型计算。结果就溢出了。

一种改进的办法:

long lvar3 = 24l * 60 * 60 * 1000 * 1000;

这样计算的结果类型是long,可以得到预期的输出了。

 

你可能感兴趣的:(java)