關於int的范圍以及溢出問題


最近在練一些算法題目的時候恰巧碰到了幾道關於int范圍與溢出相關的問題,於是就整理一下。

1、原碼、補碼

在計算機中數值都是用補碼表示和存儲的(正數補碼與原碼一致,負數補碼是原碼符號位不變,其余位取反,然后+1即反碼+1)。

可以通過將這個數每一位和1做&運算得到具體的二進制表示,代碼如下。代碼部分參考https://blog.csdn.net/youyou362/article/details/72667951

 1 /**
 2      * 將n的每一位與1做&運算 得到具體的二進制表示
 3      * @param n
 4      * @return
 5      */
 6     public static void converseToBinary(int n) {
 7         int value = 1;
 8         int[] arr = new int[32];
 9         int i = 31;
10         while (value != 0) {
11             if ((value & n) != 0) {
12                 arr[i] = 1;
13             } else {
14                 arr[i] = 0;
15             }
16             i--;
17             value = value << 1; //左移右邊補0,當移完32為value為0.
18         }
19         for (int index = 0;index < 32;index++){
20             System.out.print(arr[index]);
21             if ((index+1)%4 == 0){
22                 System.out.print(" ");
23             }
24         }
25     }

例如-3,程序運行結果為 1111 1111 1111 1111 1111 1111 1111 1101 ,正是-3的補碼。由此得知在計算機中數值都是用補碼表示和存儲的。

2、int的取值范圍

java中int四字節,一個字節8bit所以 int 32bit 即高16位和低16位,共32位,最高位符號位。

在Integer類中,有兩個常量 MIN_VALUE和MAX_VALUE是16進制的數。

 1 /**
 2      * A constant holding the minimum value an {@code int} can
 3      * have, -2<sup>31</sup>.
 4      */
 5     @Native public static final int   MIN_VALUE = 0x80000000;
 6 
 7     /**
 8      * A constant holding the maximum value an {@code int} can
 9      * have, 2<sup>31</sup>-1.
10      */
11     @Native public static final int   MAX_VALUE = 0x7fffffff;

轉化成二進制分別是MIN_VALUE = 1000 0000 0000 0000 0000 0000 0000 0000;

                               MAX_VALUE =  0111 1111 1111 1111 1111 1111 1111 1111;

網上看了好多文檔,關於最大值和最小值為什么是這兩個寫的挺模棱兩可的,一開始我猜想正數最大值的時候是因為一共32位,第一位符號位0,剩下都應該是1才是最大,得到正好是0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111,即2^31 - 1,但已這種方式推算負數最大值時進行不下去,於是用數學歸納法進行總結:

正數部分:1的補碼為 0000 0000 0000 0000 0000 0000 0000 0001;

                  2的補碼為0000 0000 ............................................. 0010 ;

                 3的補碼為 0000 0000 ............................................. 0011;

     由此推出正數最大值的補碼為 0111 1111 1111 1111 .......................1111,原碼=補碼,為2^31-1;

負數部分:-1的補碼為 1111 1111 1111 1111 1111 1111 1111 1111

                  -2的補碼為 1111 1111 1111 1111 1111 1111 1111 1110

                  -3的補碼為 1111 1111 1111 1111 1111 1111 1111 1101

                  -4的補碼為 1111 1111 1111 1111 1111 1111 1111 1100

                  由此推出負數最小值的補碼為 1000 0000 0000 0000 0000 0000 0000 0000 0000,求負數最小值補碼的原碼為-2^31

所以int的范圍為-2^31 ~ 2^31-1

3、int的溢出問題,參考自https://www.jianshu.com/p/ffc97c4d2306

溢出是針對有符號數的。

int最大值為 2^31 - 1 補碼為 0111 1111 1111 1111 1111 1111 1111 1111 1111 1111 1111 加1為 1000 0000 0000 ................0000有溢出,為-2^31

int最小值   -2^31 補碼為 1000 0000 0000 0000 0000 0000 0000 0000 0000  ,-2^31 - 1為加-1的補碼1111 1111 1111 1111 1111 1111 1111 1111

溢出為 0111 1111 1111 1111 11111 1111 1111 1111為 2^31 - 1。

 

 

本人只是個小白,以上只是個人拙見,如果有問題還請大家指出,有更好的想法歡迎大家留言,一起進步,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM