精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

不掌握 BigDecimal 的四大坑你敢用嗎?

開發
本文從精度的比較、除法運算中是否設置精度、對象初始化到轉字符串,四個角度來把 BigDecimal 的坑盡可能清晰的描述出來,以及基于這些坑得到的優秀實踐。

BigDecimal 是 Java 中的一個類,這個相信大家都是知道的。它的作用就是可以表示任意精度的十進制數,BigDecimal 提供了精確的數字運算,適用于需要高精度計算的場景,例如金融、貨幣或者稅收等涉及到金錢的地方。

與 double 和 float 不同的是,BigDecimal 對象在計算的過程中不會丟失精度,那么下面我們就來看下第一個坑,浮點精度的坑。

一、浮點精度的坑

我們先來看一個例子:

    public static void main(String[] args) {

        BigDecimal num1 = new BigDecimal("0.1");
        BigDecimal num2 = new BigDecimal("0.10");

        // false
        System.out.println(num1.equals(num2));
        // 0
        System.out.println(num1.compareTo(num2));

    }

compareTo 方法比較中,a.compareTo(b)

返回:

  • -1: a小于b
  • 0: a等于b
  • 1: a大于b。

在上方的代碼中,我們使用 new BigDecimal 的形式 new 了兩個 BigDecimal 對象,分別是 0.1 和0.10。

我們分別使用了 equals 與 compareTo 進行比較,當使用 equals 進行比較時,返回了 false,這是因為 equals 不僅比較了值是否相等,還比較了精度是否相等,源碼中是這樣寫的:

 public boolean equals(Object x) {
        if (!(x instanceof BigDecimal))
            return false;
        BigDecimal xDec = (BigDecimal) x;
        if (x == this)
            return true;
        if (scale != xDec.scale)
            return false;
        long s = this.intCompact;
        long xs = xDec.intCompact;
        if (s != INFLATED) {
            if (xs == INFLATED)
                xs = compactValFor(xDec.intVal);
            return xs == s;
        } else if (xs != INFLATED)
            return xs == compactValFor(this.intVal);

        return this.inflated().equals(xDec.inflated());
    }

所以在使用 equals 進行比較兩個 BigDecimal 的大小時,一定要注意這一點了。

簡單概括一下,如果比較兩個 BigDecimal 對象的大小,那就使用 compareTo 方法;如果嚴格比較精度的大小,那就使用 equals 方法進行比較。

上面我們知道了如何比較兩個 BigDecimal 對象的大小,equals 比較的還有他們的精度,那么精度又是如何設置的呢,這塊有沒有坑呢?

二、設置精度的坑

有的同學可能會說了,設置精度還有啥坑啊,設置了精度就好了嗎,哎對,就是這個意思,在做 BigDecimal 對象計算的時候,一定要設置精度。相反,有的同學就不喜歡設置精度,那么這 BUG 不就來了嗎。

來看一個例子:

    public static void main(String[] args) {

        BigDecimal num1 = new BigDecimal("1");
        BigDecimal num2 = new BigDecimal("3");

        BigDecimal result = num1.divide(num2); // 默認舍入模式為 UNNECESSARY,會拋出 ArithmeticException


    }

上述的代碼在執行結束之后會報錯 ArithmeticException ,這是因為默認舍入模式為 UNNECESSARY,所以會拋出 ArithmeticException。

Exception in thread "main" java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.

要解決這個異常也很容易,只需要加上精度即可。

    public static void main(String[] args) {

        BigDecimal num1 = new BigDecimal("1");
        BigDecimal num2 = new BigDecimal("3");

        BigDecimal result = num1.divide(num2, 2,RoundingMode.HALF_UP);
        // 輸出:0.33
        System.out.println(result);


    }

那么出現這個異常的原因是什么你考慮過嗎?為什么加了精度就不報錯了呢?

這個異常在源碼中也有說明:

大概意思就是如果在做 divide 運算時,如果商是一個無限小數,而操作的結果是一個精確的數字,那么就會拋出該異常。

不知道大家注意到一點沒有,就是上面做除法運算的時候,也就是 BigDecimal result = num1.divide(num2, 2,RoundingMode.HALF_UP); 這行代碼的位置,使用了一個新的變量 result 來接收結果值,因為 BigDecimal 是不可變的,因此每次進行運算都會創建一個新的 BigDecimal 對象,所以這一點也是需要注意的,創建的多了可能會產生大量的垃圾對象。

講完了精度與運算,那么你初始化的方式對嗎?

三、初始化的坑

先來看代碼:

BigDecimal num = new BigDecimal(0.1); // 使用雙精度浮點數構造
System.out.println(num); // 輸出: 0.1000000000000000055511151231257827021181583404541015625

BigDecimal num2 = new BigDecimal("0.1"); // 使用字符串構造
System.out.println(num2); // 輸出: 0.1

在使用 new BigDecimal 構造器進行初始化的時候,如果有初始值,最好使用字符串的構造方法進行初始化。

在使用 double 的構造器進行新建時,本身傳入的 0.1 就是浮點類型了,為了不丟失精度,在使用 new BigDecimal 新建時就把這個近似值完整的保留下來了。

或者就是 另外一種初始化方式 BigDecimal.valueOf(0.1);,通過看源碼可以發現,在 valueOf 的內部,將 Double 類型直接轉為了字符串了,因此也就不會存在精度丟失的問題了。

對于使用 new BigDecimal(0.1) 構造時,源碼中也已經說明了這個問題。

大體意思就是生成的 BigDecimal 對象不是我們想要的 0.1,推薦使用 String 類型的構造方法。

上面我們已經學會了如何初始化,如何運算,下一步就是如何用了,例如轉字符串,很多同學可能會說,轉字符串 toString() 不就好了,如果你也這樣想,那你單純了弟弟。

四、轉字符串的坑

還是先看一段代碼:

    public static void main(String[] args) {
        BigDecimal a = BigDecimal.valueOf(89382389312389594.33822312317952678768725);
        System.out.println(a.toString()); // 輸出:8.93823893123896E+16
        String str = a.setScale(2, RoundingMode.HALF_UP).toString();
        System.out.println(str); // 輸出: 89382389312389600.00

    }

上面代碼中是一個非常大的數,我想把他轉為字符串,可是在使用 toString() 方法時,打印出來的卻是科學計數法。

所以如果想使用 toString() 方法進行轉字符串時,可以使用設置精度的方法,但是結果還是與我們的預期有所差別,我們想要的是一模一樣的打印出來呢?

那么 toPlainString 就上場了,這個方法返回一個字符串的表示形式,包含所有的有效數字。

代碼修改如下:

    public static void main(String[] args) {
        BigDecimal a = BigDecimal.valueOf(89382389312389594.99933822312317952678768725);
        System.out.println(a.toPlainString());
    }

修改之后就可以了嗎,不可以,忘了上面說的嗎,使用 String 的構造函數吧兄弟,double 類型的構造函數會丟失精度的。

最終代碼如下:

    public static void main(String[] args) {
        BigDecimal a = new BigDecimal("89382389312389594.99933822312317952678768725");
        System.out.println(a.toPlainString());
    }

除了上述兩種轉字符串的方法外,還有一種,就是 toEngineeringString,這個方法也是返回一個字符串,包含有效數字,但是它會使用工程計數法,科學計數法的一種變體,它使用數字的倍數來表示值,使得指數是 3 的倍數。例如,1000會顯示為"1E3",而不是"1E+3"。

所以總結就是:

  • toString:返回有效數字,必要的時候使用科學計數法。
  • toPlainString: 不實用任何科學計數法。
  • toEngineeringString:必要的時候使用工程計數法。

五、總結

本文從精度的比較、除法運算中是否設置精度、對象初始化到轉字符串,四個角度來把 BigDecimal 的坑盡可能清晰的描述出來,以及基于這些坑得到的優秀實踐。

有些場景下推薦使用 BigDecimal ,但是能不用還是不用,比 double 、float 多出來的性能損失得是你能接受的。如果非得用,那上面這幾個坑一定要規避。

責任編輯:趙寧寧 來源: 醉魚Java
相關推薦

2022-07-19 07:30:06

BigDecimal運算float

2023-06-30 08:10:14

JavaBigDecimal

2022-06-06 00:25:09

Golangpanic死鎖

2025-11-13 08:22:03

2024-08-02 14:52:00

2019-10-25 21:39:39

服務器開發工具

2018-07-06 05:05:07

2025-04-29 10:00:15

NVRIPC弱電

2011-10-19 10:07:18

桌面虛擬化云計算

2018-01-31 22:30:05

數據科學家數據專家工程師

2022-02-25 08:13:03

物聯網IOT

2022-05-11 09:27:15

Linux發行版

2011-03-21 09:01:49

CSS框架

2015-07-17 09:50:16

Carthage優劣比較

2023-02-17 08:20:24

SQL腳本數據庫

2016-03-30 11:51:55

2014-11-21 09:28:13

2010-09-17 13:27:17

虛擬化

2011-02-15 09:58:27

Linux服務器系統維護

2013-01-06 10:44:43

微軟Windows 8云計算
點贊
收藏

51CTO技術棧公眾號

猫咪在线永久网站| 日本免费在线观看视频| 国产精品毛片av| 日韩欧美在线国产| 一区二区日本| 污视频网站在线播放| 日韩电影免费一区| 久久久久久国产精品美女| 人妻无码一区二区三区| 亚洲精品大全| 粉嫩av一区二区三区免费野| 亚洲一区二区精品在线观看| 五月婷中文字幕| 久久精品99国产精品| 国外色69视频在线观看| 日本二区三区视频| 一道本一区二区三区| 欧美一级生活片| 无人在线观看的免费高清视频| 中文字幕在线观看播放| 久久久久国产精品麻豆ai换脸| 成人在线观看视频网站| www.国产毛片| 亚洲精品男同| 欧美精品一本久久男人的天堂| wwwwww日本| 精品欠久久久中文字幕加勒比| 欧美色区777第一页| 久久久999视频| 影音先锋在线播放| 一区二区中文字幕在线| 欧洲成人一区二区| 色视频在线观看免费| 国产.欧美.日韩| 91免费人成网站在线观看18| 中文字幕一区二区免费| 水蜜桃久久夜色精品一区的特点| 久久久久久中文| 2021亚洲天堂| 亚洲国产精品成人| 日韩在线观看你懂的| 亚洲色成人网站www永久四虎 | 久久av色综合| 亚洲黄色片在线观看| 热这里只有精品| 久久黄色美女电影| ●精品国产综合乱码久久久久| 日韩av一区二区三区在线| 外国精品视频在线观看 | 伊人影院综合网| 免费视频亚洲| 亚洲视频专区在线| 五月天综合视频| 精品国产乱码久久久久久果冻传媒| 亚洲精品中文字幕女同| aaaa黄色片| 西野翔中文久久精品国产| 日韩av网址在线观看| 亚洲精品乱码久久久久久蜜桃图片| 一区二区三区高清在线观看| 日韩欧美一区二区久久婷婷| 91丨porny丨九色| 欧美经典一区| 亚洲国产福利在线| 亚洲激情 欧美| 美女毛片一区二区三区四区| 亚洲欧美日韩中文在线制服| 久久久久亚洲av成人无码电影| 欧美艳星介绍134位艳星| 色哟哟入口国产精品| 欧美激情精品久久久久久免费| 亚洲成人精品| 欧美国产视频一区二区| 国产成人在线播放视频| 噜噜噜躁狠狠躁狠狠精品视频| 国产精品久久久久久久久久久久久| 国产女优在线播放| 激情综合色播五月| 丁香婷婷久久久综合精品国产 | 成人禁用看黄a在线| 久久99国产精品99久久| 爱久久·www| 亚洲欧美日韩中文播放| 成人午夜视频在线观看免费| 欧美成人性网| 欧美一区二区成人| 人妻少妇精品视频一区二区三区| 欧洲grand老妇人| 久久中文字幕在线| 天堂中文字幕在线观看| 免费观看在线综合| 岛国视频一区| av小片在线| 亚洲最大的成人av| 波多野结衣作品集| 永久免费精品视频| 亚洲最新在线视频| 久久av高潮av无码av喷吹| 久久一区精品| 懂色一区二区三区av片| 国产小视频免费在线网址| 亚洲精选一二三| www.日日操| 成人台湾亚洲精品一区二区| 国产一区二区日韩| 国产真实夫妇交换视频| 青青国产91久久久久久| 精品999在线观看| 少妇精品无码一区二区免费视频| 九九久久婷婷| 欧美成人免费播放| 区一区二在线观看| 国产suv精品一区二区三区| 欧美日韩高清在线一区| 亚洲h片在线看| 日本精品一区二区三区四区的功能| 永久免费黄色片| 国产亚洲一区| 97欧美精品一区二区三区| 国产精品无码在线播放| 久久久久久久一区| 丰满少妇大力进入| 精品国模一区二区三区欧美| 国产亚洲美女精品久久久| 在线播放国产一区二区三区| av在线网址导航| 欧美三级自拍| 欧美激情网站在线观看| 国产精品久久久久久69| 国产三级精品在线| 国产肥臀一区二区福利视频| 亚洲一区电影| 欧美成人免费全部观看天天性色| 岳乳丰满一区二区三区| 国产亚洲欧美中文| 不卡影院一区二区| 欧美一级全黄| 久久久久久久久爱| www国产在线| 亚洲欧美一区二区三区国产精品 | 日韩一级av毛片| 亚洲一区区二区| 麻豆成人在线播放| 欧美男男tv网站在线播放| 精品久久久久久久人人人人传媒 | 三级黄色片在线观看| 日韩电影网1区2区| 先锋影音一区二区三区| 国产成人精品一区二区三区视频| 国产亚洲欧美aaaa| 正在播放木下凛凛xv99| 国产拍欧美日韩视频二区| 日韩精品一区中文字幕| 欧洲乱码伦视频免费| 国产精品第二页| www 日韩| 欧美美女喷水视频| 欧美黑人精品一区二区不卡| 成人在线综合网站| www一区二区www免费| 九热爱视频精品视频| 国产精品久久在线观看| 日本不卡三区| 日韩欧美国产精品一区| 香蕉视频一区二区| 久久久噜噜噜久久人人看| 日本999视频| 欧美gayvideo| av观看久久| 深夜av在线| 视频直播国产精品| 性欧美8khd高清极品| 亚洲va欧美va人人爽| 亚洲成人黄色av| 国产一区啦啦啦在线观看| 人人妻人人做人人爽| 国产一区三区在线播放| 91牛牛免费视频| 成人在线黄色电影| 中文国产成人精品| 亚洲精品一级片| 色婷婷国产精品综合在线观看| 美国一级黄色录像| 丰满放荡岳乱妇91ww| www日韩视频| 欧美a级一区| 欧美一级片免费观看| 国产色99精品9i| 97高清免费视频| 在线观看黄色av| 欧美精品一区二区不卡 | 免费精品99久久国产综合精品| 国产卡一卡二在线| 九九视频免费观看视频精品| 亚洲在线视频福利| gogo亚洲高清大胆美女人体| 欧美激情国产精品| 成在在线免费视频| 亚洲福利小视频| 中文字幕在线日亚洲9| 亚洲一区视频在线| 久操视频在线观看免费| 成人久久久精品乱码一区二区三区| 超碰影院在线观看| 一区二区亚洲精品| 久久久一二三四| 精品国产一区二区三区小蝌蚪 | 国产日韩一区| 99久久久无码国产精品性色戒| 伊人久久大香线蕉av不卡| 91pron在线| 成人国产精品一区二区免费麻豆 | 欧美91在线|欧美| 欧美重口另类videos人妖| 羞羞视频在线观看免费| 尤物yw午夜国产精品视频明星 | 天堂av一区| 国产日韩欧美在线| 色豆豆成人网| 日韩av电影免费观看高清| 国产精品—色呦呦| 久久97久久97精品免视看| 免费黄色在线| 中文字幕日韩在线观看| 久青草国产在线| 日韩经典第一页| 污视频在线免费| 亚洲第一偷拍网| 成人爽a毛片一区二区| 欧美一区二区女人| 国产美女自慰在线观看| 欧美日韩成人在线| 一二三四区在线| 欧美日韩五月天| 中文字幕精品一区二区精| 色网站国产精品| 国产免费一级视频| 日本韩国视频一区二区| 国产一区二区视频网站| 欧美视频免费在线观看| 精品人妻无码一区二区性色 | 88av在线视频| 在线不卡欧美精品一区二区三区| 中国一区二区视频| 欧美三级一区二区| 一级特黄色大片| 欧美日韩国产a| 97人妻精品一区二区三区动漫| 欧美日韩亚洲综合一区二区三区| 在线免费观看一级片| 欧美最猛黑人xxxxx猛交| 波多野结衣电车| 欧美日韩一二区| 国产又大又粗又硬| 欧美一区二区性放荡片| 亚洲av无码国产精品永久一区 | 黄色片免费在线| 国产亚洲a∨片在线观看| 国产二区在线播放| 久久久www成人免费精品| 亚洲淫性视频| 国内精品久久久| 午夜日韩成人影院| 国产精品天天狠天天看| 国产成人免费视频网站视频社区| 亚洲最大福利网| 精品嫩草影院| 视频一区视频二区视频| 一本一道久久a久久精品蜜桃| 国产精品国三级国产av| 亚洲女同在线| 亚洲天堂伊人网| 成人丝袜高跟foot| 免费一级做a爰片久久毛片潮| 国产精品婷婷午夜在线观看| 婷婷伊人五月天| 亚洲成人在线观看视频| 久久久久在线视频| 777久久久精品| 污视频软件在线观看| 最近2019中文字幕一页二页| 美足av综合网| 国产精品美女999| 日韩在线精品强乱中文字幕| 精品在线一区| 偷偷www综合久久久久久久| 欧美日韩福利在线| 日韩高清不卡在线| 一本色道久久hezyo无码| 国产人成一区二区三区影院| 欧美色图一区二区| 色婷婷综合在线| 亚洲成人77777| 国产一区二区三区丝袜| 国产一线二线在线观看| 国产精品视频免费在线| 另类在线视频| 一区二区三区一级片| 亚洲欧美激情诱惑| 亚洲 自拍 另类 欧美 丝袜| 国产性做久久久久久| 精品人妻在线播放| 欧美日韩dvd在线观看| 天天摸天天碰天天爽天天弄| 日韩中文字幕在线免费观看| 在线免费看h| 国产精品二区二区三区| 欧美呦呦网站| 国产免费观看高清视频| 国产精品亚洲一区二区三区妖精 | 欧美一区二区在线看| 黄色片视频在线观看| 亚洲 日韩 国产第一| 久久影院一区二区三区| 小说区图片区图片区另类灬| 国产精品久久久久久模特 | 97超碰人人草| 国产一区二区激情| 成人性生活视频| 精品亚洲一区二区三区四区五区高| 亚洲天堂免费| 国产美女18xxxx免费视频| 国产欧美精品在线观看| 国产一级免费视频| 日韩高清av在线| 第一福利在线视频| 成人免费视频观看视频| 欧美激情视频一区二区三区在线播放 | 久久国产精品久久精品国产| 欧美人与禽猛交乱配视频| 亚洲美女性囗交| 国产精品美女久久久久aⅴ | 精品国产乱码久久久久久影片| 国产1区在线| 成人在线视频网| 91精品国产乱码久久久久久| 欧美一级特黄a| 中文字幕精品一区二区三区精品| 五月婷婷激情视频| 亚洲欧洲一区二区三区久久| 香蕉伊大人中文在线观看| 久久99热只有频精品91密拍| 日韩午夜av| 中文字幕在线免费看线人| 天天操天天综合网| 男人的天堂在线| 日本精品久久久久久久| 日韩手机在线| 久久精品香蕉视频| 久久久精品综合| 欧美另类高清videos的特点| 在线精品国产欧美| 丁香久久综合| 国产卡一卡二在线| 国产成人一级电影| 国产午夜精品无码| 亚洲人成亚洲人成在线观看| 欧美性xxx| 亚洲一区二区在| 国产高清久久久| 日产精品久久久久久久| 亚洲精品视频在线播放| 巨胸喷奶水www久久久免费动漫| 色婷婷精品国产一区二区三区| 免费不卡在线观看| 精品国产精品国产精品| 精品久久国产老人久久综合| 性xxxxfreexxxxx欧美丶| 日韩在线国产| 国产伦精一区二区三区| 免费一级特黄特色大片| 亚洲女人天堂网| 日本a人精品| 17c丨国产丨精品视频| 91在线精品一区二区| 最好看的日本字幕mv视频大全| 久久影视电视剧免费网站| 麻豆精品少妇| 网站一区二区三区| 亚洲一区av在线| 国产区在线视频| 亚洲xxxxx电影| 久久成人精品| 538任你躁在线精品视频网站| 亚洲精品国精品久久99热一| 国产经典一区| 女人被男人躁得好爽免费视频| 久久久久久久久久久99999| 国产精品自拍电影| 7m第一福利500精品视频| 国产精品成人一区二区不卡| 亚洲一区二区在线免费| 欧美性猛交xxxxxxxx| 国产亚av手机在线观看| 午夜久久资源| 99精品欧美一区| 国产ts变态重口人妖hd| 日韩美女视频免费看| 欧美韩日精品| 网站永久看片免费|