爲何不能用浮點型表示金額?

參考博客:blog.csdn.net/bruce128/ar…java

在java中,通常來講,咱們的單精度float和雙精度double已經能夠知足咱們的大部分需求了。可是無論是float和double都會出現浮點的偏差,而這點偏差在通常狀況下並不影響咱們的使用。.net

可是,在金融行業,一個小小的精度偏差,可能會致使成千上萬的損失,甚至嚴重點來講,可能會有牢獄之災。所以,咱們必須去嚴格的計算每個小數點的值,不能出現任何偏差。3d

也所以,出現了咱們如今的這個問題,爲何不能用float和double等等等的浮點型來表示金額?cdn

看代碼: blog

結果爲:

能夠看出,隨着運算數量的上升,明顯看到偏差的產生。這是float類型的運算,若是是double類型的話,那麼偏差將會更大。ci

這是第一個緣由,使用float和double會出現偏差,這在金融行業基本上不被容許的。get

那麼,僅僅是這個緣由嗎?博客

還有一個緣由,咱們要向float和double這兩個基礎數據類型中找尋。it

這個問題和float和double在java中規定的數據長度有關。32位的浮點數float由3部分組成:1比特的符號位,8比特的階碼(exponent,指數),23比特的尾數(Mantissa,尾數)。這個結構會表示成一個小數點左邊爲1,以底數爲2的科學計數法表示的二進制小數。浮點數的能表示的數據大小範圍由階碼決定,可是可以表示的精度徹底取決於尾數的長度。而64位的浮點數double是1比特的符號位,11比特的階碼(exponent,指數),52比特的尾數(Mantissa,尾數)。io

因而,就會出現以下代碼的狀況:

結果爲:
緣由:

long的最大值是2的64次方減1,須要63個二進制位表示,即使是double,52位的尾數也沒法完整的表示long的最大值。不能表示的部分也就只能被捨去了。因此致使了添加了10億次以後,數值依然沒有變化,由於添加的數值都被捨去了。

那麼,應該怎麼辦呢?

JDK提供了一個BigDecimal的類,這個類能夠表示任意精度的數字。

相關文章
相關標籤/搜索