關于bigDecimal類的精度保留方法
一、計算機的小數計算
計算機的小數計算一定范圍內精確,超過范圍只能取近似值:
計算機存儲的浮點數受存儲bit位數影響,只能保證一定范圍內精準,超過bit范圍的只能取近似值。
java中各類型的精度范圍參見:關于java中基本數據類型的數值范圍
編程時注意:
doulbe類型的數,不能用等號判定是否相等(或者是一定范圍內可以)。因為兩次同樣的計算(除法)結果可能出現小數部分不同。甚至極端的時候,初始化兩個小數時,都可能不相等(用數值和字符串分別初始化bigdecimal的小數就會不等)
java小數處理方法的經驗總結:
(1)小數計算對精度無要求時,使用float節(jié)省時間。
(2)如果有精度要求,用BigDecimal類處理(初始化必須使用字符串,因為用數值初始化會得到近似值,不準確),然后設置保留位數和 舍入法(half_up四舍五入,half_even銀行家,half_down向下取整)
(3)精度要求低時可轉化為整數處理(集體統(tǒng)一擴大數量級):
乘以10的級數轉化為整數處理,小數點右移幾位,但整數值不要超過對應類型的取值范圍。比如保留4位小數,可統(tǒng)一乘以10000,然后只保留整數計算結果,保留近位的話就多乘一位。
這種方式在RTB項目MDSP的算法核心模塊中使用,幾十萬的投放量,用int或long就可以處理,更大范圍的整數處理BigInteger。
這樣的好處是:
a,計算快,除了除法,其他運算上整數計算(加減乘)節(jié)省時間;
b,除法中,小數部分可直接省略,或向上取整(小數大于0時則加1)也可以讓小數點多移動一位來保留進位。
二、java專門的小數運算類:
BigDecimal類型(比double和float小數運算更精準的小數計算)
float和double只能用來做科學計算或者是工程計算,在廣域數值范圍上提供較為精確的快速近似計算;而在商業(yè)計算要求結果精確(比如,有的編程語言中提供了專門的貨幣類型來處理),所以Java使用java.math.BigDecimal專門處理小數精度
構造器描述:
BigDecimal(int) 創(chuàng)建一個具有參數所指定整數值的對象。
BigDecimal(double) 創(chuàng)建一個具有參數所指定雙精度值的對象。
BigDecimal(long) 創(chuàng)建一個具有參數所指定長整數值的對象。
BigDecimal(String) 創(chuàng)建一個具有參數所指定以字符串表示的數值的對象。
使用原則:初始化小數必須用String來夠造,BigDecimal(String),因為用double的小數是近似值,不是精確值。
BigDecimal成員方法
add(BigDecimal) 對象自身與參數相加,然后返回這個對象。
subtract(BigDecimal) 對象自身與參數相減,然后返回這個對象。
multiply(BigDecimal) 對象自身與參數相乘,然后返回這個對象。
divide(BigDecimal) 對象自身與參數相除,然后返回這個對象。
toString() BigDecimal對象的數值轉換成對應的字符串。
doubleValue() BigDecimal對返回double值。
floatValue() BigDecimal對返回float。
longValue() BigDecimal對返回long值。
intValue() BigDecimal對返回int值。
三、java小數保留精度的舍入方式
1,java 常用的四舍五入法實現:
Math類中的round方法不能設置保留幾位小數,但可以乘100達到保留2位的目的:
Math.round(value*100)/100.0;
或者,直接用java.text.DecimalFormat指定保留幾位小數,用哪幾種舍入法:
DecimalFormat decFormat = new DecimalFormat("#.00"); decFormat.setRoundingMode(RoundingMode.HALF_UP);
2,java的8種舍入方式:
1、 ROUND_UP:向上取整(丟掉小數,整數加1) 遠離零方向舍入。向絕對值最大的方向舍入,只要舍棄位非0即進位。
2、ROUND_DOWN:向下取整(丟掉小數)。趨向零方向舍入。向絕對值最小的方向輸入,所有的位都要舍棄,不存在進位情況。
3、ROUND_CEILING:向正無窮方向走,始終不會減少計算值。如果 BigDecimal 為正,則舍入行為與 ROUND_UP 相同;如果為負,則舍入行為與 ROUND_DOWN 相同。Math.round()方法就是使用的此模式。
4、ROUND_FLOOR:向負無窮方向舍入。向負無窮方向靠攏。若是正數,舍入行為類似于ROUND_DOWN;若為負數,舍入行為類似于ROUND_UP。
5、 HALF_UP:四舍五入,最近數字舍入(5進)。
6、 HALF_DOWN:四舍六入,最近數字舍入(5舍)。
7、 HAIL_EVEN:銀行家舍入法。四舍六入五偶舍。即舍棄位4舍6入,當為5時看前一位,奇進偶舍。向“最接近的”數字舍入,如果與兩個相鄰數字的距離相等,則向相鄰的偶數舍入。
也就是說,如果舍棄部分左邊的數字為奇數,則舍入行為與 ROUND_HALF_UP 相同; 如果為偶數,則舍入行為與 ROUND_HALF_DOWN 相同。
注意,在重復進行一系列計算時,此舍入模式可以將累加錯誤減到最小。
8、ROUND_UNNECESSARY 斷言請求的操作具有精確的結果,因此不需要舍入。如果對獲得精確結果的操作指定此舍入模式,則拋出ArithmeticException。
到此這篇關于關于bigDecimal類的精度保留方法的文章就介紹到這了,更多相關bigDecimal精度保留內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!