1. 程式人生 > >int與Long需要注意的值範圍

int與Long需要注意的值範圍

今天使用程式計算一個算式,算出的結果一點不對,當時就氣死我了。

然後用計算器算了好幾遍,先證明自己邏輯沒有混亂。

這個算式什麼樣子?

System.out.println( "不加L,丟失精度:"+(-1387053568*31 + 19287));

執行結果:明顯不對。

不加L,丟失精度:-48968361

這個計算肯定超過了int的最大值,所以使用Long算一下,

System.out.println( "加上L,正確結果:"+(-1387053568L*31 + 19287));

結果正確:

加上L,正確結果:-42998641321

接著思考這個是怎麼丟失精度的:

先列出int最大,最小值:

System.out.println("測試Integer的值:");
        System.out.println( "最大:"+Integer.MAX_VALUE);
        System.out.println( "最小:"+Integer.MIN_VALUE);

結果:

測試Integer的值:
最大:2147483647
最小:-2147483648

猜想是不是利用最小的值進行計算的:

System.out.println( "猜想是不是溢位後變成最小值計算,模擬:"+(Integer.MIN_VALUE*31 + 19287));

結果不是用最小值進行計算的,因為與上面的結果不一致:

猜想是不是溢位後變成最小值計算,模擬:-2147464361

看一下這個轉換,這樣就看出丟失精度的過程了:乘法的時候數值超過int最小值範圍,先轉換為一個數,用這個數加的19287

 int i =-1387053568*31;
        System.out.println("輸出int溢位值:"+i);

溢位結果:

輸出int溢位值:-48987648

這個int超過值範圍是怎麼計算的:這就涉及導java的溢位機制,

涉及到,先轉為二進位制,然後擷取32位(int型別4個位元組,1個位元組八位),然後正負數的補碼,反碼等操作,再轉回十進位制。

有空再繼續寫一下把。//TODO

最後所有程式:

System.out.println("測試Integer的值:");
        System.out.println( "最大:"+Integer.MAX_VALUE);
        System.out.println( "最小:"+Integer.MIN_VALUE);
        int i =-1387053568*31;
        System.out.println("輸出int溢位值:"+i);
        System.out.println( "加上L,正確結果:"+(-1387053568L*31 + 19287));
        System.out.println( "不加L,丟失精度:"+(-1387053568*31 + 19287));
        System.out.println( "猜想是不是溢位後變成最小值計算,模擬:"+(Integer.MIN_VALUE*31 + 19287));
        System.out.println((int)(-1387053568L*31+ 19287));
        //十進位制轉換為二進位制
        //二進位制擷取低位32位   原碼   補碼  反碼之類,這裡沒寫完,有興趣可以瞭解一下
        String a=Long.toBinaryString((int)(-1387053568L*31));
        System.out.println(a);
        String sub =a.substring(a.length()-32,a.length());
        System.out.println(sub);
        System.out.println(sub.length());
        System.out.println(Long.valueOf(sub,2).toString());

結果:

測試Integer的值:
最大:2147483647
最小:-2147483648
輸出int溢位值:-48987648
加上L,正確結果:-42998641321
不加L,丟失精度:-48968361
猜想是不是溢位後變成最小值計算,模擬:-2147464361
-48968361
1111111111111111111111111111111111111101000101001000001000000000
11111101000101001000001000000000
32
4245979648