1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        電商金額計(jì)算的 4 個(gè)坑,千萬(wàn)注意了!

        共 4564字,需瀏覽 10分鐘

         ·

        2021-06-01 19:25

        上一篇:深夜看了張一鳴的微博,讓我越想越后怕

        作者:叁滴水
        來(lái)源:https://blog.csdn.net/qq_30285985/

        前言

        電商項(xiàng)目開(kāi)發(fā)時(shí)肯定少不了金額計(jì)算,金額計(jì)算時(shí)有很多讓人坑人的地方,在此記錄,以免被坑。

        1、多精度計(jì)算問(wèn)題

        多精度不能直接計(jì)算,會(huì)存在經(jīng)度缺失的問(wèn)題。

        public static void main (String[] args) {
          double num1 = 1;
          double num2 = 31.2;
          double num3 = 323.03;
          System.out.println (num1+num2+num3);
          /**
           * 355.22999999999996
           */
        }

        如上代碼,3 個(gè)數(shù)值想加之后卻得出了一個(gè)很長(zhǎng)的數(shù)值。

        在 java 開(kāi)發(fā)中可以通過(guò) BigDecimal 進(jìn)行數(shù)值類(lèi)型的計(jì)算,詳細(xì)可到 BigDecimal 工具類(lèi)。

        數(shù)據(jù)庫(kù)也是一樣,mysql中有float和double類(lèi)型,通過(guò)sql直接累加數(shù)據(jù)也會(huì)有精度缺失的情況。如果要精確的數(shù)值計(jì)算,要使用mysql的decimal類(lèi)型。

        2、包裝類(lèi)型比對(duì)

        public static void main(String[] args) {
             Integer i1 = 100;
             Integer i2 = 100;
             Integer i3 = 200;
             Integer i4 = 200;
             System.out.println(i1==i2); // true
             System.out.println(i3==i4);  // false
        }

        如上代碼很神奇,同樣是數(shù)值比對(duì)100的時(shí)候可以通過(guò)雙等號(hào)返回true。200就返回false。

        這是因?yàn)镮nteger的valueOf()方法。

        //Integer的valueOf方法
        public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
        }

        在[-128,128]之間的數(shù),可以通過(guò)雙等于比對(duì)成功,之外的數(shù)值就會(huì)返回一個(gè)new一個(gè)新的Integer,因此會(huì)返回false。Double的比較就簡(jiǎn)單一點(diǎn),雙等于比對(duì)全是false。這是因?yàn)镈ouble直接是返回了一個(gè)新的Double。

        //Double的valueOf方法
        public static Double valueOf(String s) throws NumberFormatException {
            return new Double(parseDouble(s));
        }

        在數(shù)值比對(duì)的時(shí)候亂的樣子,那我發(fā)現(xiàn)他們都有eq方法,通過(guò)這個(gè)方法比對(duì)可以嗎?金融系統(tǒng)中正確的金額計(jì)算及存儲(chǔ)方式這篇看下。

        可以的,不管是Integer還是Double都存在一個(gè)equas方法,通過(guò)這個(gè)方法即可進(jìn)行數(shù)值比對(duì)。但是這個(gè)方法不是很完美。

        public static void main (String[] args){
          Double i1 = 100d;
          System.out.println(i1.equals ("100")); 
          //false
        }

        如上所示,因?yàn)樘嗟娜硕贾雷址?lèi)型不能用雙等號(hào)進(jìn)行比對(duì),要用eq方法進(jìn)行比對(duì)其value。

        這樣會(huì)讓很多人誤以為Integer和Double類(lèi)型也是如此,而且在編碼的時(shí)候如上這種寫(xiě)法也沒(méi)有報(bào)錯(cuò),會(huì)認(rèn)為都是100肯定會(huì)返回true。恰巧這種想法是錯(cuò)誤的。

        public boolean equals(Object obj) {
            return (obj instanceof Double)
                   && (doubleToLongBits(((Double)obj).value) ==
                          doubleToLongBits(value));
        }

        Double的eq方法入?yún)⑹荗bject類(lèi)型,因此不管傳入什么類(lèi)型都不會(huì)報(bào)錯(cuò)。i1.equals ("100")這種就是雙精度和字符進(jìn)行比對(duì),這兩個(gè)永遠(yuǎn)都不可能返回true。正確的寫(xiě)法應(yīng)該是i1.equals (100d)。

        但是盡管多次提醒,但是還是會(huì)有不認(rèn)真的開(kāi)發(fā)小伙伴錯(cuò)誤,因此,可以使用Double.compareTo方法,這個(gè)方法和eq方法類(lèi)似,但是有編譯的異常,這樣可有效的提醒開(kāi)發(fā)人員。

        public static void main (String[] args){
          Double i1 = 100d;
          System.out.println(i1.compareTo (100d)); //0
          System.out.println(i1.compareTo (1d));  //1
        }

        3、除以0會(huì)怎樣?

        小學(xué)的時(shí)候就講過(guò),進(jìn)行除法運(yùn)算時(shí),除以0是沒(méi)有意義的,開(kāi)發(fā)過(guò)程中也是如此, 發(fā)現(xiàn)可能存在除以0的場(chǎng)景要特別注意,程序不會(huì)拋出異常,竟然會(huì)返回一個(gè)字符串!雖然這種場(chǎng)景不多,但是還是需要了解一下。

        1除以0的場(chǎng)景:

        public static void main(String[] args) {
          Double d = 1d;
          double v = d / 0d;
          System.out.println(v);
          //Infinity
        }

        0除以0的場(chǎng)景:

        public static void main(String[] args) {
          Double d = 0d;
          double v = d / 0d;
          System.out.println(v);
          //NaN
        }

        4、float轉(zhuǎn)double

        public static void main(String[] args) {
         Float f = 12312.12f;
         System.out.println(f.doubleValue()); 
         System.out.println(Double.parseDouble (f.toString ())); 
         //12312.1201171875
         //12312.12
        }

        Float類(lèi)中有一個(gè)doubleValue方法,返回值是一個(gè)double類(lèi)型,這樣會(huì)很容易的以為這是float轉(zhuǎn)換double類(lèi)型。但是轉(zhuǎn)換之后精度缺失了,只能乖乖的換一種方式轉(zhuǎn)換。


        感謝您的閱讀,也歡迎您發(fā)表關(guān)于這篇文章的任何建議,關(guān)注我,技術(shù)不迷茫!小編到你上高速。


            · END ·
        最后,關(guān)注公眾號(hào)互聯(lián)網(wǎng)架構(gòu)師,在后臺(tái)回復(fù):2T,可以獲取我整理的 Java 系列面試題和答案,非常齊全。


        正文結(jié)束


        推薦閱讀 ↓↓↓

        1.不認(rèn)命,從10年流水線(xiàn)工人,到谷歌上班的程序媛,一位湖南妹子的勵(lì)志故事

        2.如何才能成為優(yōu)秀的架構(gòu)師?

        3.從零開(kāi)始搭建創(chuàng)業(yè)公司后臺(tái)技術(shù)棧

        4.程序員一般可以從什么平臺(tái)接私活?

        5.37歲程序員被裁,120天沒(méi)找到工作,無(wú)奈去小公司,結(jié)果懵了...

        6.IntelliJ IDEA 2019.3 首個(gè)最新訪(fǎng)問(wèn)版本發(fā)布,新特性搶先看

        7.漫畫(huà):程序員相親圖鑒,笑屎我了~

        8.15張圖看懂瞎忙和高效的區(qū)別!

        一個(gè)人學(xué)習(xí)、工作很迷茫?


        點(diǎn)擊「閱讀原文」加入我們的小圈子!


        瀏覽 34
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            黄色成人在线视频 | 一级a免一级a做免费线看内裤 | 鲁一鲁色一色鲁寡妇 | 国产精品嫩草AV | 插插插插插插插插色域综合网 | 91在线无码精品秘 入口九色十 | 草的我好爽 | 操大奶妹子 | 美女色色网站 | 丰满女人的毛片久久久久久 |