談談Java基本數據類型
說到Java的基本數據類型,我們可能都能想到4類8種基本數據類型:
1、整型 byte、short、int、long分別用8、16、32、64bits來存儲。
2、浮點型fl點型float、double分別用32/64bits來存儲。
3、字符型char用16bits存儲。
4、布爾型boolean可以用1bits來存儲,其實布爾型沒有明確的大寫規定,jvm在編譯期間會將boolean類型轉換爲int類型,用0表示true,用1表示false。
說說基本數據類型int的取值範圍
也許進入工作崗位後,我們很多的人都還記得每種基本數據類型佔多少位,但是很多的人都會忘了每種基本數據類型的取值範圍(boolean除外)。在三年前的一次面試中面試官上來的第一個問題就是int的取值範圍,當時我只答出了32位,尷尬的氣氛導致連用科學計數的方式,都沒說出int的最大取值範圍與最小取值範圍。直到面試結束在回去的地鐵上才捋清思維想到了【-2^31,2^31 -1】。
爲了讓大家更清楚的記得,每種基本數據類型的取值範圍,我在這裏和大家一起,以4bits數爲例進行一次最大、最小值的推演。
我們都知道計算機底層都是以二進制存儲,以4位二進制數爲例,其最大值爲1111等於10進制的2^3+2^2+2^1+2^0=8+4+2+1=15。但很顯然這樣是不行的,因爲我們的整數包含正數和負數,所以必須的用一位來作爲標誌,表示該整數是正數還是負數。如下圖以最高位爲0表示正數:
0
1
|
0 | 000 |
0 | 001 | |
0 | 010 | |
0 | 011 | |
0 | 100 | |
0 | 101 | |
0 | 110 | |
0 | 111 |
0
-1
|
1 | 000 |
1 | 001 | |
1 | 010 | |
1 | 011 | |
1 | 100 | |
1 | 101 | |
1 | 110 | |
1 | 111 |
我相信聰明的你一定會發現一個問題,就是0出現了兩次一個正0一個負0,很顯然這樣是不妥的。因爲我們都知道0既不是正數也不是負數,那怎麼辦呢?這個時候我們必須引入一個名詞:“補碼”,我們可以使用補碼來表示負數,補碼是啥呢,對二進制數的所有位取反然後加1得到的就是這個二進制數的補碼。
於是我們只需在特殊處理負0爲-8,其他負數除符號位外取補碼即可,於是有:
補碼
-1
-2
|
1 | 111 |
1 | 110 | |
1 | 101 | |
1 | 100 | |
1 | 011 | |
1 | 010 | |
1 | 001 | |
1 | 000 |
由此我們可以推算int的最大值爲:0111...111即:2^(32-2) + 2^(32-3) + ... + 2^ + 2^0這裏我們套用等比數列前n項和公式:Sn=a1(1-q^n)/(1-q)得到int的最大取值範圍爲:2^31-1。
同理我們可以得到int的最小取值範圍爲:-2^31。
基本數據類型的強制轉化與自動轉化
基本數據類型默認支持向上的自動轉型,也就是說小的數據類型可以自動轉化爲大的數據類型,大的數據類型必須強制申明才能轉換成小的數據類型。演示代碼如下:
int a = 1;
byte b = 2;
int c = b; //自動向上轉型
byte d = (byte)a; //必須強制轉換
單精度浮點數float和雙精度浮點數double
關於浮點數的使用
在使用和計算浮點數的時候:如果我們沒有在浮點數後面加上F或者f,則浮點數都會默認被轉化爲double。
浮點數爲什麼不精確?
怎麼來理解這句話呢,通俗一點說就是我們現實生活中習慣使用的10進制小數,在計算機底層無法用二進制的小數來精確的表達。
例如二進制小數1.11等於十進制的 2^0 + 2^-1 + 2^-2 = 1 + 1/2 + 1/4 = 1.75.
同理我們再來計算一個十進制小數0.3
0.1 = 1/2 = 0.5 大了
0.01 = 1/4 = 0.25 小了
0.011 = 1/4 + 1/8 = 0.25 + 0.125 = 0.375 又大了
0.0101 = 1/8 + 1/32 = 0.25 + 0.03125 = 0.28125 又小了但是靠進0.3了
0.01011 = 1/8 + 1/32 + 1/64 = 0.25 + 0.03125 + 0.015625 = 0.296875 又近了
差不得了哈哈約等於0.3了
由此可見浮點數是不精確的,如果我們要進行精確計算可以使用BigDecimal類。
“重走Java路-Java基本數據類型”的分享就到此結束了,預知後文請聽下回分解“重走Java路-基本數據類型的包裝類及引用數據類型”。