<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

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

          共 4457字,需瀏覽 9分鐘

           ·

          2021-05-29 12:09

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

          前言

          電商項(xiàng)目開發(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 開發(fā)中可以通過(guò) BigDecimal 進(jìn)行數(shù)值類型的計(jì)算,詳細(xì)可到 BigDecimal 工具類。

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

          2、包裝類型比對(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ì)可以嗎?

          可以的,不管是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)樘嗟娜硕贾雷址愋筒荒苡秒p等號(hào)進(jìn)行比對(duì),要用eq方法進(jìn)行比對(duì)其value。

          這樣會(huì)讓很多人誤以為Integer和Double類型也是如此,而且在編碼的時(shí)候如上這種寫法也沒(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類型,因此不管傳入什么類型都不會(huì)報(bào)錯(cuò)。i1.equals ("100")這種就是雙精度和字符進(jìn)行比對(duì),這兩個(gè)永遠(yuǎn)都不可能返回true。正確的寫法應(yīng)該是i1.equals (100d)。

          但是盡管多次提醒,但是還是會(huì)有不認(rèn)真的開發(fā)小伙伴錯(cuò)誤,因此,可以使用Double.compareTo方法,這個(gè)方法和eq方法類似,但是有編譯的異常,這樣可有效的提醒開發(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)有意義的,開發(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類中有一個(gè)doubleValue方法,返回值是一個(gè)double類型,這樣會(huì)很容易的以為這是float轉(zhuǎn)換double類型。但是轉(zhuǎn)換之后精度缺失了,只能乖乖的換一種方式轉(zhuǎn)換。

          1. 記一次性能優(yōu)化,單臺(tái) 4 核 8G 機(jī)器支撐 5 萬(wàn) QPS

          2. 數(shù)據(jù)庫(kù)連接池為什么要用threadlocal呢?不用會(huì)怎樣?

          3. 一次深夜優(yōu)化,MySQL億級(jí)數(shù)據(jù)分頁(yè)的奇妙經(jīng)歷

          4. 一條 update 語(yǔ)句引起的事故,這回讓開發(fā)長(zhǎng)長(zhǎng)記性!!

          最近面試BAT,整理一份面試資料Java面試BATJ通關(guān)手冊(cè),覆蓋了Java核心技術(shù)、JVM、Java并發(fā)、SSM、微服務(wù)、數(shù)據(jù)庫(kù)、數(shù)據(jù)結(jié)構(gòu)等等。

          獲取方式:點(diǎn)“在看”,關(guān)注公眾號(hào)并回復(fù) Java 領(lǐng)取,更多內(nèi)容陸續(xù)奉上。

          文章有幫助的話,在看,轉(zhuǎn)發(fā)吧。

          謝謝支持喲 (*^__^*)

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

          手機(jī)掃一掃分享

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

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  麻豆成人入口 | 狠狠干天天操 | 色婷婷国产精品秘 免 | 91在线成人免费视频 | www.久久草 |