日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

BigDecimal的个人总结

發(fā)布時間:2024/7/23 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 BigDecimal的个人总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

前言:
互聯(lián)網(wǎng)公司,對于BigDecimal的使用,還是較為頻繁的,那么就會涉及到關(guān)于這個類型的種種問題.

1:為什么使用BigDecimal
首先java八大基本類型真的很基本,4個整型搞不了小數(shù),double和float搞的了小數(shù),但搞不好,關(guān)鍵時刻就調(diào)鏈子,當(dāng)然這也和他們存儲方式有關(guān)(二進(jìn)制無法精確的表示1/10),天生注定搞不了精密計算,尤其是和錢相關(guān)的.

所以一般我們對于精密點(diǎn)的計算和涉及貨幣的計算,都會使用BigDecimal.他的出現(xiàn),就是為了解決基本數(shù)據(jù)類型浮點(diǎn)數(shù)不能進(jìn)行精確計算的問題.

2:如何使用BigDecimal
就說最常用的:
2.1.初始化,一般使用這個構(gòu)造方法:new BigDecimal(String value);
其他的不再多說,某度很多,只能說我們一般都會用這個String類型的入?yún)?/p> 關(guān)于BigDecimal的初始化,有一個坑要注意,就是盡量使用String類型的去初始化。 不信的話,可以看看下面的例子:BigDecimal a = new BigDecimal(1.01);BigDecimal b = new BigDecimal(1.02);BigDecimal c = new BigDecimal("1.01");BigDecimal d = new BigDecimal("1.02");System.out.println(a.add(b));System.out.println(c.add(d)); 最終的打印結(jié)果是: 2.0300000000000000266453525910037569701671600341796875 2.03 很明顯,也是精度問題。這塊要注意。

2.2.基本運(yùn)算

add(BigDecimal) BigDecimal對象中的值相加,然后返回這個對象。 subtract(BigDecimal) BigDecimal對象中的值相減,然后返回這個對象。 multiply(BigDecimal) BigDecimal對象中的值相乘,然后返回這個對象。 divide(BigDecimal) BigDecimal對象中的值相除,然后返回這個對象。 toString() 將BigDecimal對象中的值以字符串形式返回。 doubleValue() 將BigDecimal對象中的值以雙精度數(shù)返回。 floatValue() 將BigDecimal對象中的值以單精度數(shù)返回。 longValue() 將BigDecimal對象中的值以長整數(shù)返回。 intValue() 將BigDecimal對象中的值以整數(shù)返回。

3.采坑經(jīng)驗(敲黑板的重點(diǎn)!!!)
3.1.將BigDecimal類性的值(10.1000)傳給頁面后,頁面展示的(10.1000)不是我們想要的(10.1),該怎么處理?

BigDecimal money;public BigDecimal getMoney() {return money;}最開始上面的這種處理方式,如果money是10.1000,那么get方法也會拿到10.1000,但其實(shí)我們想要的是10.1就好了. ------------------------------------------------------------------------- 那怎么辦,直接上最終版(重寫個getMoneyString方法):public String getMoneyString() {return money.stripTrailingZeros().toPlainString();}這個方法返回的,就是10.1,String類型的 --------------------------------------------------------------------------解釋下:1.stripTrailingZeros()方法官方文檔對返回的解釋是:a numerically equal BigDecimal with any trailing zeros removed.而且從方法名就可以看出來,就是去掉末尾的0.那么,為什么還要用toPlainString()方法呢?看個例子:new BigDecimal("60000.000").stripTrailingZeros();這個結(jié)果是6E+4,而不是我們想要的60000,而且官方文檔上也說明了,返回的值,會用科學(xué)計數(shù)法來表示,所以看下個方法2.toPlainString()官方文檔對返回的解釋是:a string representation of this BigDecimal without an exponent field.就是返回一個不用指數(shù)表示的字符串形式的值.所以兩個方法連用,就可以達(dá)到對BigDecimal的初步控制.

3.2.值的比較用compareTo,不要用equals
compareTo:左邊比右邊數(shù)大,返回1,相等返回0,比右邊小返回-1
equals:BigDecimal重寫了equals,比較的是數(shù)值

3.3.除法要養(yǎng)成習(xí)慣去設(shè)置精度,以免出現(xiàn)無限循環(huán)的小數(shù)而拋異常
(java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result)

new BigDecimal("10").divide(new BigDecimal("3")); 這個就會拋出上面的異常.所以要用下面的new BigDecimal("10").divide(new BigDecimal("3"), 4, BigDecimal.ROUND_HALF_DOWN); 這個代表10除以3,結(jié)果保留4位小數(shù),采用四舍五入保留 所以結(jié)果就是:3.3333

3.4.既然用了BigDecimal了,就應(yīng)避免再與浮點(diǎn)類型互相轉(zhuǎn)換,否則精度會受很大的影響

4.BigDecimal格式化
可以使用NumberFormat類的format(BigDecimal)方法,利用NumberFormat不同類型的實(shí)例,對BigDecimal轉(zhuǎn)換不同的格式.詳細(xì)可以查查NumberFormat的各種實(shí)例方法,比如:
NumberFormat.getCurrencyInstance();
NumberFormat.getCurrencyInstance();
NumberFormat.getInstance();

根據(jù)不同的需求,使用不同的格式…
下面提供兩個現(xiàn)成的轉(zhuǎn)換精度的方法

/**** @param obj 傳入的BigDecimal類型* @return 返回String類型,保留兩位小數(shù)(四舍五入),不夠補(bǔ)0*/public static String formatToStringWithTwoPlaces(BigDecimal obj) {DecimalFormat df = new DecimalFormat("#.00");if (obj.compareTo(BigDecimal.ZERO) == 0) {return "0.00";} else if (obj.compareTo(BigDecimal.ZERO) > 0 && obj.compareTo(new BigDecimal(1)) < 0) {return "0" + df.format(obj).toString();} else {return df.format(obj).toString();}}//這個方法效果和上一個一樣,兩種不同的實(shí)現(xiàn)罷了public static String getDecimalStr(BigDecimal bd) {String bdStr;if (bd != null) {bdStr = bd.setScale(2, RoundingMode.HALF_EVEN).toPlainString();} else {bdStr = "0.00";}return bdStr;}public static void main(String[] args) {//各種類型測試BigDecimal bigDecimal1 = new BigDecimal("0");System.out.println(formatToStringWithTwoPlaces(bigDecimal1));//0.00BigDecimal bigDecimal11 = new BigDecimal("0.6");System.out.println(formatToStringWithTwoPlaces(bigDecimal11));//0.60BigDecimal bigDecimal12 = new BigDecimal("0.6666");System.out.println(formatToStringWithTwoPlaces(bigDecimal12));//0.67BigDecimal bigDecimal2 = new BigDecimal("2");System.out.println(formatToStringWithTwoPlaces(bigDecimal2));//2.00BigDecimal bigDecimal3 = new BigDecimal("2.1");System.out.println(formatToStringWithTwoPlaces(bigDecimal3));//2.10BigDecimal bigDecimal4 = new BigDecimal("2.22");System.out.println(formatToStringWithTwoPlaces(bigDecimal4));//2.22BigDecimal bigDecimal5 = new BigDecimal("2.333");System.out.println(formatToStringWithTwoPlaces(bigDecimal5));//2.33BigDecimal bigDecimal15 = new BigDecimal("0");System.out.println(getDecimalStr(bigDecimal15));//0.00BigDecimal bigDecimal115 = new BigDecimal("0.6");System.out.println(getDecimalStr(bigDecimal115));//0.60BigDecimal bigDecimal125 = new BigDecimal("0.6666");System.out.println(ConvertUtil.getDecimalStr(bigDecimal125));//0.67BigDecimal bigDecimal25 = new BigDecimal("2");System.out.println(getDecimalStr(bigDecimal25));//2.00BigDecimal bigDecimal35 = new BigDecimal("2.1");System.out.println(getDecimalStr(bigDecimal35));//2.10BigDecimal bigDecimal45 = new BigDecimal("2.22");System.out.println(getDecimalStr(bigDecimal45));//2.22BigDecimal bigDecimal55 = new BigDecimal("2.333");System.out.println(getDecimalStr(bigDecimal55));//2.33}

5.BigDecimal取整

public static void main(String[] args) {BigDecimal bigDecimal = new BigDecimal(6.66);//6.66除以6,向上取整,結(jié)果為2BigDecimal divide = bigDecimal.divide(BigDecimal.valueOf(6),0, BigDecimal.ROUND_UP);System.out.println(divide);//2//6.66除以6,不報錯,但有這么多小數(shù)跟在后面BigDecimal divide2 = bigDecimal.divide(BigDecimal.valueOf(6), BigDecimal.ROUND_UP);System.out.println(divide2);//1.110000000000000023684757858670006195704142252605//1.110000000000000023684757858670006195704142252605向上取整,結(jié)果為2BigDecimal bigDecimal1 = divide2.setScale(0, BigDecimal.ROUND_UP);System.out.println(bigDecimal1);//6.66除以6,報錯:java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.BigDecimal divide1 = bigDecimal.divide(BigDecimal.valueOf(6));System.out.println(divide1);//報錯}

各個roundingMode詳解如下:
ROUND_UP:非0時,舍棄小數(shù)后(整數(shù)部分)加1,比如1.11結(jié)果為2,-1.11結(jié)果為 -2
ROUND_DOWN:直接舍棄小數(shù)
ROUND_CEILING:如果 BigDecimal 是正的,則做 ROUND_UP 操作;如果為負(fù),則做 ROUND_DOWN 操作 (一句話:取附近較大的整數(shù))
ROUND_FLOOR: 如果 BigDecimal 是正的,則做 ROUND_DOWN 操作;如果為負(fù),則做 ROUND_UP 操作(一句話:取附近較小的整數(shù))
ROUND_HALF_UP:四舍五入(取更近的整數(shù))
ROUND_HALF_DOWN:跟ROUND_HALF_UP 差別僅在于0.5時會向下取整
ROUND_HALF_EVEN:取最近的偶數(shù)
ROUND_UNNECESSARY:不需要取整,如果存在小數(shù)位,就拋ArithmeticException 異常

總結(jié)

以上是生活随笔為你收集整理的BigDecimal的个人总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。