精品欧美一区二区三区在线观看 _久久久久国色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高清在线免费观看| 午夜福利视频一区二区| 玖玖精品视频| 俺去啦;欧美日韩| 制服下的诱惑暮生| av中文在线资源库| 久久婷婷国产综合国色天香| 国产精品精品一区二区三区午夜版| 国产高潮呻吟久久| 成人51免费| 亚洲国产毛片aaaaa无费看| 精品在线观看一区二区| 中国a一片一级一片| 黄色亚洲大片免费在线观看| 国产香蕉一区二区三区在线视频 | 九色综合日本| 国产精品高潮呻吟AV无码| 先锋a资源在线看亚洲| 久久天天躁夜夜躁狠狠躁2022| 成人免费无码大片a毛片| 国产一区精品二区| 欧美三级韩国三级日本三斤 | 日本亚洲天堂网| 欧美极品在线视频| 精品无码一区二区三区蜜臀| 少妇精品久久久一区二区| 精品卡一卡二卡三卡四在线| 一起操在线视频| av在线日韩| 精品国产91久久久| 男人添女人荫蒂免费视频| 国产网站在线免费观看 | 欧美黄色aaa| 国产永久免费高清在线观看视频| 台湾天天综合人成在线| 日韩欧美一区二区三区久久| a级黄色小视频| 欧美四级在线| 亚洲精品ww久久久久久p站| 久久av秘一区二区三区| 懂色av中文在线| 久久天堂av综合合色蜜桃网| 久草热久草热线频97精品| 亚洲不卡免费视频| 国产精品中文字幕日韩精品| 成人性生交大片免费看小说| 一级片在线免费观看视频| 肉色丝袜一区二区| 国产精品国产自产拍高清av水多| 亚洲成人第一网站| 久久三级福利| 国产精品激情av在线播放| 中国黄色一级视频| 欧美aaa在线| 国产精品视频播放| 一级黄色片免费| 韩国三级中文字幕hd久久精品| 成人国产精品日本在线| 一区二区三区免费观看视频| 日韩国产精品久久| 国产精品免费一区二区三区都可以| 欧美brazzers| 人人精品人人爱| 成人在线视频网站| 国产高清免费观看| 成人精品视频一区| 你懂的网址一区二区三区| 黄色片在线播放| 国产精品乱码人人做人人爱 | 欧美美女搞黄| 国产精品无码永久免费888| 香蕉视频在线网址| 天堂av中文在线| 精品久久久久久久久国产字幕| 人妻精品无码一区二区三区 | 在线精品亚洲| 热久久美女精品天天吊色| 精品美女久久久久| 青青草一区二区三区| 91精品久久久久久久久久| 丰满肥臀噗嗤啊x99av| 久久久久九九视频| 天天综合中文字幕| 欧美激情20| 欧美久久一二区| 国产婷婷在线观看| 日韩成人免费| 久久久视频免费观看| 天码人妻一区二区三区在线看| 久久精品国产99国产| 99中文字幕| 亚洲一区二区精品在线| 欧美日韩电影在线| 成人av动漫在线| 偷偷www综合久久久久久久| 最近在线中文字幕| 无码国产伦一区二区三区视频| 久久久美女视频| www.超碰97.com| 老熟妇一区二区| 欧洲乱码伦视频免费| 日韩中文字幕国产| 国产成人在线播放视频| 久久www免费人成看片高清| 国产伦精品一区二区三区视频黑人 | 天天影院图片亚洲| 国产精品欧美经典| 久久久999视频| 国产精久久久| 亚洲最新视频在线| 免费一级a毛片夜夜看| 美女视频黄久久| 精品视频在线观看| 日本色护士高潮视频在线观看| 欧美三级电影精品| 人妻少妇一区二区| 影音先锋中文字幕一区| 91色在线观看| 日本www在线观看| 91福利区一区二区三区| 欧洲一级黄色片| 亚洲人人精品| 国产66精品久久久久999小说| 永久av在线| 欧美亚洲国产一区在线观看网站| 亚洲第一黄色网址| 国色天香一区二区| 99久久无色码| av毛片在线看| 日韩三级免费观看| 国产成人av免费在线观看| 美女性感视频久久| 少妇精品久久久久久久久久| 人人视频精品| 亚洲欧美在线x视频| www.天天色| 成人综合婷婷国产精品久久蜜臀 | 国内视频一区二区| 国产精品186在线观看在线播放| 91精品国产综合久久福利软件| 一级片黄色录像| 久久电影网站中文字幕| 亚洲国产另类久久久精品极度| 26uuu亚洲电影| 亚洲欧美综合另类中字| 亚洲天堂一区在线| 久久久午夜精品理论片中文字幕| 日本毛片在线免费观看| 亚洲+小说+欧美+激情+另类| 性色av一区二区三区红粉影视| 手机看片福利在线| 精品久久中文字幕久久av| 亚洲国产综合视频| 久久精品人人做人人爽电影蜜月| 免费中文日韩| 欧美高清你懂的| 大量国产精品视频| 亚洲av无码专区在线| 性欧美疯狂xxxxbbbb| 麻豆国产精品一区| 日韩和的一区二区| 国产又爽又黄ai换脸| 午夜视频在线观看精品中文 | 国产欧美一区二区三区精品酒店| 亚洲欧美色图片| 亚洲最大成人在线视频| 亚洲欧美日韩一区| 青青草视频网站| 久久久久国产精品午夜一区| 色姑娘综合网| 欧美成年网站| 国产91精品黑色丝袜高跟鞋| av中文天堂在线| 欧美一区二区成人| 在线观看亚洲欧美| 中文字幕不卡在线| 亚洲国产欧美日韩在线| 午夜亚洲影视| 亚洲午夜在线观看| 国产精品白丝av嫩草影院| 日韩暖暖在线视频| 国产精品一卡二卡三卡| 精品久久国产97色综合| 狠狠人妻久久久久久综合| 成人欧美一区二区三区视频网页 | 伊人久久大香线蕉综合网蜜芽| 国产精品久久婷婷六月丁香| 亚洲无线看天堂av| 亚洲午夜精品视频| 亚洲成人一二三区| 欧美性感一区二区三区| 久久精品波多野结衣| 国产欧美中文在线| 美女网站视频在线观看| 日韩中文字幕麻豆| 国产成人永久免费视频| 精品一区二区三区中文字幕老牛| 国产精品免费区二区三区观看| 亚洲精品粉嫩美女一区| 久久久久久久久久久亚洲| 成人免费视频| 亚洲国产中文字幕久久网| 伊人网中文字幕| 精品福利樱桃av导航| 国产精品老熟女一区二区| 久久九九久精品国产免费直播| 国产人妻精品午夜福利免费| 麻豆久久久久久| 国产女女做受ⅹxx高潮| 国内综合精品午夜久久资源| 在线码字幕一区| 欧美激情在线精品一区二区三区| 国产超碰91| 24小时成人在线视频| 国产精品成人免费电影| 午夜激情电影在线播放| 欧美极品欧美精品欧美视频| 国产丝袜在线| 在线精品高清中文字幕| 欧洲一区av| 亚洲国产精品福利| 亚洲精品成人电影| 91精品国产综合久久久久久| 中文字幕av片| 欧美亚洲国产bt| 日韩国产成人在线| 日本韩国一区二区三区| 日本视频www| 亚洲高清久久久| 免费在线观看亚洲| 亚洲欧美另类久久久精品2019| а天堂中文在线资源| 国产精品美女视频| xxxx成人| 国产一区网站| 性色av一区二区咪爱| 牛牛精品在线视频| 久久电影一区二区| 好操啊在线观看免费视频| 中文字幕免费精品一区| 免费黄色片在线观看| 精品综合免费视频观看| 欧美亚洲精品一区二区| 亚洲精品黄色| 国产91在线免费| 亚洲免费一区二区| av免费观看网| 丝瓜av网站精品一区二区 | 国产午夜福利一区| 国产人伦精品一区二区| 久久视频精品在线观看| 欧美国产日本视频| 午夜国产福利视频| 日韩毛片一二三区| 老妇女50岁三级| 亚洲图片一区二区| 啦啦啦免费高清视频在线观看| 欧美性极品xxxx娇小| 中文字幕xxxx| 91精品国产入口| 成人免费公开视频| 日韩国产精品一区| 69久久久久| 操91在线视频| 精品人人视频| 国产精品美女久久久久av超清| 999精品视频在线观看| 99精品国产高清一区二区| 久久夜色电影| 亚洲福利av在线| 综合天天久久| 丰满爆乳一区二区三区| 日本午夜精品视频在线观看| 最好看的中文字幕| 91最新地址在线播放| 长河落日免费高清观看| 一区二区三区视频在线看| 青青青国产在线 | 综合久久久久久久| 日韩精品在线免费看| 欧美自拍丝袜亚洲| 国内老熟妇对白xxxxhd| 日韩精品欧美激情| 在线观看免费高清完整| 久久久久在线观看| 国产美女久久| 国产一区二区无遮挡| 99久久精品网站| 免费观看美女裸体网站| 蜜臀av一级做a爰片久久| 亚洲美女精品视频| 中文字幕第一区二区| 日韩xxxxxxxxx| 欧美精品久久久久久久久老牛影院 | 免费在线观看a级片| 欧美日韩另类在线| 国产绳艺sm调教室论坛| 国产一区二区三区四区福利| 男男gaygays亚洲| 国产在线观看91精品一区| 奇米影视777在线欧美电影观看| 正在播放91九色| 日韩和欧美一区二区三区| 亚洲一区二区在线免费| 亚洲欧洲精品天堂一级 | 91精品国产综合久久精品| 韩日视频在线| 91精品国产九九九久久久亚洲| 精品一区二区三区中文字幕| 香蕉久久免费影视| 免费日韩av片| 粉嫩av懂色av蜜臀av分享| 亚洲蜜桃精久久久久久久| a片在线免费观看| 亚洲天堂免费观看| 蜜桃av.网站在线观看| 亚洲自拍偷拍在线| 99久久九九| 超碰在线人人爱| 久久精品免费在线观看| 国产情侣在线视频| 精品国产乱码久久久久久夜甘婷婷 | 在线观看黄色国产| 亚洲香蕉av在线一区二区三区| 涩涩视频在线| 国内精品国语自产拍在线观看| 欧美成人中文| 91av免费观看| 一区二区在线观看不卡| 99久久精品国产一区二区成人| 日韩在线播放视频| 色猫猫成人app| 色999日韩自偷自拍美女| 天堂蜜桃91精品| 男人操女人动态图| 在线亚洲精品福利网址导航| 免费在线超碰| 国产精品av免费在线观看| 国产99久久精品一区二区300| 欧美日韩国产精品激情在线播放| 99精品一区二区三区| 久久久午夜影院| 日韩精品在线视频观看| 欧美gay视频| 日产精品高清视频免费| 日韩高清不卡一区二区| 亚洲精品电影院| 9191成人精品久久| 中文字幕中文字幕在线十八区| 99精彩视频| 一道本一区二区| 亚洲码无人客一区二区三区| 欧美色大人视频| 欧洲不卡视频| 99久久久久国产精品免费 | 精品久久久久久中文字幕2017| 国产午夜精品久久久久久免费视| 精品乱码一区内射人妻无码| 北条麻妃一区二区三区中文字幕| 欧美特黄不卡| 激情伊人五月天| 国产午夜精品一区二区三区嫩草 | 亚洲精品aⅴ中文字幕乱码| 中文字幕高清在线播放| 日韩欧美一区二区视频在线播放| 久久国产综合精品| 久久久全国免费视频| 日韩精品高清在线观看| 巨胸喷奶水www久久久免费动漫| 日韩视频在线观看视频| 99久久777色| 亚洲综合免费视频| 欧美高清激情视频| 亚洲日本三级| 岛国av免费在线| 欧美日韩国产激情| 日本在线人成| 国产欧美一区二区三区另类精品| 天堂蜜桃一区二区三区| 日韩欧美中文字幕视频| 国产视频一区在线| 国产区一区二| 无码人妻丰满熟妇区五十路百度| 中文字幕国产一区| 天堂在线视频免费| 国产日韩欧美电影在线观看| 亚洲免费成人| 91香蕉一区二区三区在线观看| 精品国产一区二区三区忘忧草| 456亚洲精品成人影院| 男人日女人的bb| 日本一区二区三区四区| 狠狠躁日日躁夜夜躁av| 国产精品影片在线观看| 国产日韩欧美一区|