一、各數據類型的最大值和最小值
整數:
以byte爲例,我們知道,byte共有8個bit位,最大值是0111111,最小值是10000000,用十進制來表示就是-128~127,即-2^7~2^7。
依照上面的推理方式可知
總結下表:
數據類型 | bit位 | 取值範圍 |
byte | 8 | -2^7~2^7-1 |
short | 16 | -2^15~2^15-1 |
int | 32 | -2^32~2^32-1 |
long | 64 | -2^63~2^63-1 |
小數:
我們知道float是32位,double爲64位,分別被叫做單精度和雙精度小數。但是他們的最大值卻不是通過上面的代碼來確定的,我們用代碼來看看它們的最大值是多少:
System.out.println("float的最大值:"+Float.MAX_VALUE); System.out.println("double的最大值:"+Double.MAX_VALUE);
運行結果:
float的最大值:3.4028235E38 double的最大值:1.7976931348623157E308
通過上面的代碼,我們知道了float的最大值爲3.4*10^38,double的最大值爲1.79*10^308。
那爲什麼同樣是32位的int和64位的long無法表示呢?
我們來看看存儲結構:
由於二進制比較麻煩,我們用十進制來表示。
整數的存儲很簡單,第一位爲符號位,其他剩餘位都表示數值,例如
0 | 9 | 9 | 9 |
第一位爲符號位,後面的三位則均爲數字位,所以,這表示的就是999。
但是小數的存儲方法就不相同:
符號位 | 指數位(階碼位) | 尾數位(小數位) |
以double第一位和整數一樣是符號位,之後的指數位共有11位,剩下的位數全部是尾數位,以double爲例,double的尾數位就是52位。
還是剛纔的數值:
0 | 9 | 9 | 9 |
這就是爲什麼同樣位數的小數要比整數表示的數字要大。
二、精確度
我們首先用int 和float表示相同的一個數字:
int a = 12345678; float b = 12345678; System.out.println("int:"+a); System.out.println("float:"+b);
運行結果:
int:12345678 float:1.2345678E7
此時,int和float的值結果是相同的,當他們表示一個更大的數時就會出現如下問題:
int a = 123456789; float b = 123456789; System.out.println("int:"+a); System.out.println("float:"+b);
運行結果:
int:123456789 float:1.23456792E8
此時,float丟失了一個數字8,現在我們再用double來表示這個數字:
double c = 123456789; System.out.println("double:"+c);
運行結果:
double:1.23456789E8
我們驚奇的發現:double沒有丟失數據!
正如我們上面說的,float是32位,double爲64位,float之所以出現丟失數據的顯現,是因爲float的位數不足以存儲123456789,所以部分數據就丟失了,但是double有64位,小數位足以表示123456789,因此就不會發生數據丟失。
三、強制數據類型轉換
高精度->低精度
從高精度轉爲低精度時會發生精度丟失的狀況,例如:
double a = 123.45; int b = (int) a; System.out.println(b);
運行結果:
123
可見,由double轉爲int時,會將小數部分丟掉。
高位->低位
位數多的轉爲位數少的會發生高位數據丟失,例如:
int a = 129; byte b = (byte) a; System.out.println(b);
運行結果:
-127
我們知道,int爲32位,129用二進制表示就是00000000 00000000 00000000 10000001。在強轉爲byte時,由於byte只有8位,會將前24位全部舍掉,剩下的就是10000001,轉爲十進制就是-127。