- 資訊首頁(yè) > 開(kāi)發(fā)技術(shù) >
- 淺談Java基礎知識之BigDecimal
使用示例:
// 初始化 BigDecimal bd1=new BigDecimal("456"); BigDecimal bd2=new BigDecimal("123"); // 加 BigDecimal add=bd1.add(bd2); // 減 BigDecimal subtract=bd1.subtract(bd2); // 乘 BigDecimal multiply=bd1.multiply(bd2); // 除 BigDecimal divide=bd1.divide(bd2); // 指數運算, 2 is exponent BigDecimal powerValue=bd2.pow(2); // 四舍五入 multiply.setScale(1, RoundingMode.HALF_EVEN);
枚舉類(lèi) java.math.RoundingMode
定義了8種數據的舍入模式,在 BigDecimal
中,可以用 BigDecimal.setScale(int newScale, RoundingMode roundingMode)
來(lái)設置數據的精度和舍入模式。
ROUND_UP
:向遠離零的方向舍入。ROUND_DOWN
:向接近零的方向舍入。ROUND_CEILING
:向正無(wú)窮大的方向舍入。BigDecimal
為正,則舍入行為與 ROUND_UP
相同;若為負,則舍入行為與 ROUND_DOWN
相同。即為向上取整模式。ROUND_FLOOR
:向負無(wú)窮大的方向舍入。BigDecimal
為正,則舍入行為與 ROUND_DOWN
相同;若為負,則舍入行為與 ROUND_UP
相同。即為向下取整模式。ROUND_HALF_UP
:向“最接近的”整數舍入。ROUND_HALF_DOWN
:向“最接近的”整數舍入。ROUND_HALF_EVEN
:向“最接近的”整數舍入。ROUND_UNNECESSARY
1.大量的數學(xué)計算時(shí),使用 基本數據類(lèi)型
而不是BigInteger
和 BigDecimal
。
原因:由于是不可變(immutable)的,在進(jìn)行每一步運算時(shí),都會(huì )產(chǎn)生一個(gè)新的對象,引起開(kāi)銷(xiāo)。
建議:應盡量用long
,float
,double
等基本類(lèi)型做科學(xué)計算或者工程計算。
設計的目的是用來(lái)精確地表示大整數和小數,例如進(jìn)行金額等比較敏感的數據運算。
2.構造 BigDecimal
時(shí),使用 String
而不是 double
。
原因:有些數字用 double 根本無(wú)法精確表示,傳給 BigDecimal 構造方法時(shí)就已經(jīng)不精確了。例如:new BigDecimal(0.1)得到的值是0.1000000000000000055511151231257827021181583404541015625。
建議:使用 new BigDecimal(“0.1”) 得到的值是 0.1。
BigDecimal
有4個(gè)構造方法,其中的兩個(gè)用BigInteger
構造,一個(gè)用double
構造,一個(gè)用String
構造。
3.比較兩個(gè) BigDecimal
值時(shí),使用 compareTo()
而不是 equals()
。
原因: equals() 方法認為 0.1 和 0.1 是相等的,返回true;認為 0.10 和 0.1 是不等的,返回false。
compareTo() 方法則認為 0.1 與 0.1 相等,0.10 與 0.1 也相等。
4.另外還有一些情形,任意精度的小數運算仍不能表示精確結果。例如,1 除以 9 會(huì )產(chǎn)生無(wú)限循環(huán)的小數 .111111…。
出于這個(gè)原因,在進(jìn)行除法運算時(shí),BigDecimal可以讓您顯式地控制舍入。
在使用BigDecimal數據類(lèi)型進(jìn)行計算時(shí),會(huì )有三種情況拋出 ArithmeticException
,分別是:
1.當除數為 0 時(shí),這種情況比較常見(jiàn),所以我們在進(jìn)行除法運算之前先判斷下除數是否為 0;
2.如果運算的結果是無(wú)線(xiàn)循環(huán)的小數,并且在除的時(shí)候沒(méi)有對結果設置精確的位數;
BigDecimal divide 方法結果為無(wú)限小數問(wèn)題 10/3=3.3333333333333333…
public static void main(String[] args) { BigDecimal a = new BigDecimal("10"); BigDecimal o = new BigDecimal("3"); System.out.print(a.divide(o,2, BigDecimal.ROUND_DOWN).doubleValue()); }
Note:不設置精度范圍會(huì )出現異常
3.當我們設置了結果的舍入模式是 ROUND_UNNECESSARY
模式時(shí):
如果確保了計算的結果是精確的,則不會(huì )拋出異常;否則,就會(huì )拋出ArithmeticException
異常。
4.只設置精度(小數點(diǎn)后面的位數,scale),但沒(méi)有設置舍入模式(roundingModel)時(shí),會(huì )不知道如何對小數舍入而報錯。
所以在設置精度時(shí)要連舍入模式一起設置。
// wrong code bd = new BigDecimal(1.5); // is actually 1.4999.... bd.setScale(1); // throws ArithmeticException // wright code a = new BigDecimal("2.5"); // digit left of 5 is even, so round down b = new BigDecimal("1.5"); // digit left of 5 is odd, so round up a.setScale(0, BigDecimal.ROUND_HALF_EVEN).toString() // => 2 b.setScale(0, BigDecimal.ROUND_HALF_EVEN).toString() // => 2
5.指數運算,指數 exponent 為負數時(shí)
If you are raising things to negative exponents, you must specify a MathContext in BigDecimal.pow(int, MathContext) so it knows how much precision to use – otherwise, BigDecimal will try to compute it to infinite precision, which is not possible for some values.
//wrong code BigDecimal powerValue=bd2.pow(-27);// -27 is exponent
到此這篇關(guān)于淺談Java基礎知識之BigDecimal的文章就介紹到這了,更多相關(guān)Java BigDecimal內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng )、來(lái)自本網(wǎng)站內容采集于網(wǎng)絡(luò )互聯(lián)網(wǎng)轉載等其它媒體和分享為主,內容觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如侵犯了原作者的版權,請告知一經(jīng)查實(shí),將立刻刪除涉嫌侵權內容,聯(lián)系我們QQ:712375056,同時(shí)歡迎投稿傳遞力量。
Copyright ? 2009-2022 56dr.com. All Rights Reserved. 特網(wǎng)科技 特網(wǎng)云 版權所有 特網(wǎng)科技 粵ICP備16109289號
域名注冊服務(wù)機構:阿里云計算有限公司(萬(wàn)網(wǎng)) 域名服務(wù)機構:煙臺帝思普網(wǎng)絡(luò )科技有限公司(DNSPod) CDN服務(wù):阿里云計算有限公司 百度云 中國互聯(lián)網(wǎng)舉報中心 增值電信業(yè)務(wù)經(jīng)營(yíng)許可證B2
建議您使用Chrome、Firefox、Edge、IE10及以上版本和360等主流瀏覽器瀏覽本網(wǎng)站