最近在面試時,碰到這樣一個問題:在問到項目部分時,面試官問我:你的項目中用到的分數、金額之類的數字是用的什麼數據類型? 我沒有過多思考脫口而出:double!隨後面試官又問:爲啥不用float?java
聽到這個問題,腦子裏居然忽然有些懵,回答道:double用着順手因此就用了,面試事後我本身在聽錄音覆盤時(遠程線上面試)聽到本身的回答不禁得扶額苦笑,後面又對這一塊的內容進行了回顧加深。web
float(單精度浮點數)和double(雙精度浮點數)的主要區別以下:面試
1)有效數字位數不一樣spa
單精度浮點數有效數字爲8位.net
雙精度浮點數有效數字爲16位code
也就是說由於有效數字位數不一樣,因此雙精度的double要比單精度的float要更精準一些。orm
2)數值取值範圍不一樣blog
單精度浮點數的表示範圍:-3.40E+38~3.40E+38內存
雙精度浮點數的表示範圍:-1.79E+308~1.79E+308ci
3.40E+38的意思是3.4*10的38次方,而1.79E+308指的是1.79*10的308次方,因此double的取值範圍要遠遠大於float
3)內存中佔有的字節數不一樣
單精度浮點數在內存中佔4個字節
雙精度浮點數在內存中佔8個字節
也就是說雙精度的double要比單精度的float更佔內存
4)在程序中的處理速度不一樣
通常來講,CPU處理單精度浮點數的速度比處理雙精度浮點數快
在程序中默認小數爲double類型,因此若是要用float的話,必須進行強轉
public static void main(String[] args){
float a = 1.1;
}
複製代碼
好比我寫了上面的代碼的話,在程序中就會編譯報錯,正確的寫法應該爲以下的代碼:
public static void main(String[] args){
float a = (float)1.1;
float b = 1.1f;
}
複製代碼
手動強轉或者在小數後面加f表示爲float類型(f不區分大小寫)
在使用float時須要注意一點:float 是8位有效數字,好比說有以下代碼:
public static void main(String[] args){
float a = 1.11111111111f;
System.out.println(a);
}
複製代碼
最終的輸出結果爲:1.1111112
這裏有一個疑問,不管第九位是否大於5,在取值的時候都會向第八位進1。
以上就是double和float的區別
在總結double和float的區別時,我發如今真實開發中針對金額的存儲並不是如我以前思考的同樣使用double或者float,爲啥?讓咱們看下面一段代碼:
public static void main(String[] args) {
double a=0.03;
double b=0.02;
double c=a-b;
System.out.println(c);
}
複製代碼
對於這段代碼的執行結果,大部分人可能會想確定是0.01啊!可是運行以後會驚奇的發現結果竟然是0.009999999999999998,由於float與double都是浮點數,浮點數參與的運算一般伴隨着由於沒法精確表示而進行的近似與舍入,因此致使結果會有一些誤差,而涉及到金額的計算是絕對不容許存在誤差的。
那麼應該怎麼表示金額呢?
有兩種解決方案:第一種是存儲金額時以分或釐爲單位存儲一個整數,第二種是使用BigDecimal這種數據類型來表示金額。
對於第一種是我目前在寫項目時採用的,第二種暫時並未作嘗試。
面試官問的小小的一個問題居然藏有這麼多玄機和學問,不禁得讓我汗顏,歸根結底仍是本身的知識面不夠廣。不過這也算是面試中的一些小小收穫吧,能發現本身的不足並及時補足。
本文已在CSDN同步上傳:面試官問我存儲金額應該用哪一種數據類型,我竟這樣回答