日期:2014-05-20  浏览次数:20592 次

我发现了一个诡异的问题
我本来想测试一下自动打包会浪费多少效率,用一个长整型做结果,累加正整数,

源代码如下:
Java code

package mytest;

public final class TestAutoBoxing {
    public strictfp  static  void  main( String... args ) {
        long  t;
        t = System.nanoTime();
        Long  sum1 = 0L;  // change to long will get 10 times performance!!!
        for( int i = 0; i < Integer.MAX_VALUE; ++i ) sum1 += i;
        System.out.println( System.nanoTime() - t );
        System.out.println( sum1 );
        
        t = System.nanoTime();
        long  sum2 = 0L;  // change to long will get 10 times performance!!!
        for( int i = 0; i < Integer.MAX_VALUE; ++i ) sum2 += i;
        System.out.println( System.nanoTime() - t );
        System.out.println( sum2 );
    }
}




输出结果却让我大吃一惊sum1和sum2不一样,用Long得到的结果是对的
12436407079
2305843005992468481
909358895
2305842973780213896

后来发现将i改成long,或者将循环条件改成Integer.MAX_VALUE-1,sum2均能得到正确结果。

然而很明显,i并没有超出整型int的范围。我用javap命令得到上述代码后半部分的指令如下:
Java code

Compiled from "TestAutoBoxing.java"
public final class mytest.TestAutoBoxing extends java.lang.Object{
public mytest.TestAutoBoxing();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static strictfp void main(java.lang.String[]);
  Code:
   0:   invokestatic    #2; //Method java/lang/System.nanoTime:()J
   3:   lstore_1
   4:   lconst_0
   5:   lstore_3
   6:   iconst_0
   7:   istore  5
   9:   iload   5
   11:  ldc     #3; //int 2147483647
   13:  if_icmpge       28
   16:  lload_3
   17:  iload   5
   19:  i2l
   20:  ladd
   21:  lstore_3
   22:  iinc    5, 1
   25:  goto    9
   28:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   31:  invokestatic    #2; //Method java/lang/System.nanoTime:()J
   34:  lload_1
   35:  lsub
   36:  invokevirtual   #5; //Method java/io/PrintStream.println:(J)V
   39:  getstatic       #4; //Field java/lang/System.out:Ljava/io/PrintStream;
   42:  lload_3
   43:  invokevirtual   #5; //Method java/io/PrintStream.println:(J)V
   46:  return

}



也没有看出什么问题。我的编译器是javac 1.6.0_24,求解。



------解决方案--------------------
java 1.6.0_25 木有问题
------解决方案--------------------
而且差值刚好多了
Java code

        long sum3 = 0;
        for(int i = 1;i<=15;i++)
        {
            sum3 += Integer.MAX_VALUE - i;
        }

------解决方案--------------------
我的没有问题,运算比的慢了些
22166703271
2305843005992468481
2957734366
2305843005992468481
------解决方案--------------------
没有任何问题啊
------解决方案--------------------
没问题
估计是版本的问题?