面試官問我存儲金額應該用哪種數據類型,我竟這樣回答

前言

​ 最近在面試時,碰到這樣一個問題:在問到項目部分時,面試官問我:你的項目中用到的分數、金額之類的數字是用的什麼數據類型? 我沒有過多思考脫口而出:double!隨後面試官又問:為啥不用float?

面試官問我存儲金額應該用哪種數據類型,我竟這樣回答


​ 聽到這個問題,腦子裡竟然突然有些懵,回答道:double用著順手所以就用了,面試過後我自己在聽錄音覆盤時(遠程線上面試)聽到自己的回答不由得扶額苦笑,後面又對這一塊的內容進行了回顧加深。

double和float的區別

float(單精度浮點數)和double(雙精度浮點數)的主要區別如下:

​ 1)有效數字位數不同

​ 單精度浮點數有效數字為8位

​ 雙精度浮點數有效數字為16位

​ 也就是說因為有效數字位數不同,所以雙精度的double要比單精度的float要更精準一些。

​ 2)數值取值範圍不同

​ 單精度浮點數的表示範圍:-3.40E+38~3.40E+38

​ 雙精度浮點數的表示範圍:-1.79E+308~1.79E+308

​ 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的話,必須進行強轉

<code>public static void main(String[] args){
	float a = 1.1;	
}/<code>

比如我寫了上面的代碼的話,在程序中就會編譯報錯,正確的寫法應該為如下的代碼:

<code>public static void main(String[] args){
    float a = (float)1.1;
    float b = 1.1f;
}/<code>

手動強轉或者在小數後面加f表示為float類型(f不區分大小寫)

在使用float時需要注意一點:float 是8位有效數字,比如說有如下代碼:

<code>public static void main(String[] args){
    float a = 1.11111111111f;
    System.out.println(a);
}/<code>

最終的輸出結果為:1.1111112

這裡有一個疑問,無論第九位是否大於5,在取值的時候都會向第八位進1。

以上就是double和float的區別

金額到底應該用哪種數據類型?

​ 在總結double和float的區別時,我發現在真實開發中針對金額的存儲並非如我之前思考的一樣使用double或者float,為啥?讓我們看下面一段代碼:

<code>public static void main(String[] args) {
     double a=0.03;
     double b=0.02;
     double c=a-b;
     System.out.println(c);
}/<code>

​ 對於這段代碼的執行結果,大部分人可能會想肯定是0.01啊!但是運行之後會驚奇的發現結果居然是0.009999999999999998,因為float與double都是浮點數,浮點數參與的運算通常伴隨著因為無法精確表示而進行的近似與舍入,所以導致結果會有一些偏差,而涉及到金額的計算是絕對不允許存在偏差的。

​ 那麼應該怎麼表示金額呢?

​ 有兩種解決方案:第一種是存儲金額時以分或釐為單位存儲一個整數,第二種是使用BigDecimal這種數據類型來表示金額。

​ 對於第一種是我目前在寫項目時採用的,第二種暫時並未做嘗試。

總結

面試官問的小小的一個問題竟然藏有這麼多玄機和學問,不由得讓我汗顏,歸根結底還是自己的知識面不夠廣。不過這也算是面試中的一些小小收穫吧,能發現自己的不足並及時補足。



分享到:


相關文章: