Java中基本數據類型、不能用浮點數表示金額

 

轉載請註明原文地址:http://www.javashuo.com/article/p-kgxzueic-ea.htmlhtml

 

一:8種基本數據類型

    8種基本數據類型(4整,2浮,1符,1布)數組

    整型:byte(最小的數據類型)、short(短整型)、int(整型)、long(長整型);ide

    浮點型:float(浮點型)、double(雙精度浮點型);函數

    字符型:char(字符型);spa

    布爾型:boolean(布爾型)。code

 

 

二: 整型中 byte、short、int、long 取值範圍:記住存儲位數便可

    byte:一個字節有8位,去掉符號位還有7位,正數爲避免進位還要減1,所以byte的取值範圍爲:-2^7 ~ (2^7-1),也就是 -128~127 之間。htm

    short:short用16位存儲,去掉符號位還有15位,正數爲避免進位還要減1,所以short的取值範圍是:-2^15 ~ (2^15-1)。blog

    int:整型用32位存儲,去掉符號位還有31位,正數爲避免進位還要減1,所以整型的取值範圍是 -2^31 ~ (2^31-1)。ci

    long:長整型用64位存儲,去掉符號位還有63位,正數爲避免進位還要減1,所以長整型的取值範圍是 -2^63 ~ (2^63-1)。字符串

 

三:浮點型數據

    浮點類型是指用於表示小數的數據類型。

 

    單精度和雙精度的區別:

    單精度浮點型float,用32位存儲,1位爲符號位, 指數8位, 尾數23位,即:float的精度是23位,能精確表達23位的數,超過就被截取。

    雙精度浮點型double,用64位存儲,1位符號位,11位指數,52位尾數,即:double的精度是52位,能精確表達52位的數,超過就被截取。

 

    雙精度類型double比單精度類型float具備更高的精度,和更大的表示範圍,經常用於科學計算等高精度場合。

 

    浮點數與小數的區別:

    1)在賦值或者存儲中浮點類型的精度有限,float是23位,double是52位。

    2)在計算機實際處理和運算過程當中,浮點數本質上是以二進制形式存在的。

    3)二進制所能表示的兩個相鄰的浮點值之間存在必定的間隙,浮點值越大,這個間隙也會越大。若是此時對較大的浮點數進行操做時,浮點數的精度問題就會產生,甚至出現一些「不正常"的現象。

 

四:不能用浮點數來表示金額

   1)精度丟失問題  

    從上面咱們能夠知道,float的精度是23位,double精度是63位。在存儲或運算過程中,當超出精度時,超出部分會被截掉,由此就會形成偏差。

    對於金額而言,捨去不能表示的部分,損失也就產生了。
    

    2)進制轉換偏差

    從上面咱們能夠知道,在計算機實際處理和運算過程當中,浮點數本質上是以二進制形式存在的。

    而十進制的0.1在二進制下將是一個無限循環小數,這就會致使偏差的出現。

    若是一個小數不是2的負整數次冪,用浮點數表示必然產生浮點偏差。

    換言之:A進制下的有限小數,轉換到B進制下極有多是無限小數,偏差也由此產生。

 

    浮點數不精確的根本緣由在於:尾數部分的位數是固定的,一旦須要表示的數字的精度高於浮點數的精度,那麼必然產生偏差

   

    解決這個問題的方法是BigDecimal的類,這個類能夠表示任意精度的數字,其原理是:用字符串存儲數字,轉換爲數組來模擬大數,實現兩個數組的數學運算並將結果返回。

 

五:BigDecimal的使用要點

    一、BigDecimal變量初始化——必須用傳入String的構造方法

BigDecimal num1 = new BigDecimal(0.005);//用數值轉換成大數,有偏差
BigDecimal num12 = new BigDecimal("0.005");//用字符串轉換成大數,無偏差

    由於:不是全部的浮點數都可以被精確的表示成一個double 類型值,有些浮點數值不可以被精確的表示成 double 類型值時,它會被表示成與它最接近的 double 類型的值,此時用它來初始化一個大數,會「先形成了偏差,再用產生了偏差的值生成大數」,也就是「將錯就錯」。

 

    二、使用除法函數在divide的時候要設置各類參數,要精確的小數位數和舍入模式,其中有8種舍入模式:

1、ROUND_UP

遠離零的舍入模式。

在丟棄非零部分以前始終增長數字(始終對非零捨棄部分前面的數字加1)。

注意,此舍入模式始終不會減小計算值的大小。


2、ROUND_DOWN

接近零的舍入模式。

在丟棄某部分以前始終不增長數字(從不對捨棄部分前面的數字加1,即截短)。

注意,此舍入模式始終不會增長計算值的大小。


3、ROUND_CEILING

接近正無窮大的舍入模式。

若是 BigDecimal 爲正,則舍入行爲與 ROUND_UP 相同;

若是爲負,則舍入行爲與 ROUND_DOWN 相同。

注意,此舍入模式始終不會減小計算值。


4、ROUND_FLOOR

接近負無窮大的舍入模式。

若是 BigDecimal 爲正,則舍入行爲與 ROUND_DOWN 相同;

若是爲負,則舍入行爲與 ROUND_UP 相同。

注意,此舍入模式始終不會增長計算值。


5、ROUND_HALF_UP

向「最接近的」數字舍入,若是與兩個相鄰數字的距離相等,則爲向上舍入的舍入模式。

若是捨棄部分 >= 0.5,則舍入行爲與 ROUND_UP 相同;不然舍入行爲與 ROUND_DOWN 相同。

注意,這是咱們大多數人在小學時就學過的舍入模式(四捨五入)。


6、ROUND_HALF_DOWN

向「最接近的」數字舍入,若是與兩個相鄰數字的距離相等,則爲上舍入的舍入模式。

若是捨棄部分 > 0.5,則舍入行爲與 ROUND_UP 相同;不然舍入行爲與 ROUND_DOWN 相同(五舍六入)。


7、ROUND_HALF_EVEN

向「最接近的」數字舍入,若是與兩個相鄰數字的距離相等,則向相鄰的偶數舍入。

若是捨棄部分左邊的數字爲奇數,則舍入行爲與 ROUND_HALF_UP 相同;

若是爲偶數,則舍入行爲與 ROUND_HALF_DOWN 相同。

注意,在重複進行一系列計算時,此舍入模式能夠將累加錯誤減到最小。

此舍入模式也稱爲「銀行家舍入法」,主要在美國使用。

若是前一位爲奇數,則入位,不然捨去。

如下例子爲保留小數點1位,那麼這種舍入方式下的結果。

1.15>1.2 1.25>1.2


8、ROUND_UNNECESSARY

斷言請求的操做具備精確的結果,所以不須要舍入。

若是對得到精確結果的操做指定此舍入模式,則拋出ArithmeticException。

 

六:BigDecimal源碼閱讀

    Todo。     

 

七:Todo

    大數運算的實現:https://www.cnblogs.com/hdwang/p/7642783.html

相關文章
相關標籤/搜索