91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Java?Double相加出現的問題有哪些

發布時間:2021-12-13 11:05:55 來源:億速云 閱讀:253 作者:iii 欄目:開發技術

這篇文章主要介紹“Java Double相加出現的問題有哪些”,在日常操作中,相信很多人在Java Double相加出現的問題有哪些問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”Java Double相加出現的問題有哪些”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

    Java Double相加出現的怪事

    問題的提出

    編譯運行下面這個程序會看到什么

    public class test {
     public static void main(String args[]) {
      System.out.println(0.05 + 0.01);
      System.out.println(1.0 - 0.42);
      System.out.println(4.015 * 100);
      System.out.println(123.3 / 100);
     }
    };

    你沒有看錯!結果確實是

    0.060000000000000005
    0.5800000000000001
    401.49999999999994
    1.2329999999999999

    Java中的簡單浮點數類型float和double不能夠進行運算。不光是Java,在其它很多編程語言中也有這樣的問題。在大多數情況下,計算的結果是準確的,但是多試幾次(可以做一個循環)就可以試出類似上面的錯誤。現在終于理解為什么要有BCD碼了。

    這個問題相當嚴重,如果你有9.999999999999元,你的計算機是不會認為你可以購買10元的商品的。

    在有的編程語言中提供了專門的貨幣類型來處理這種情況,但是Java沒有。現在讓我們看看如何解決這個問題。

    解決方案

    現在我們已經可以解決這個問題了,原則是使用BigDecimal并且一定要用String來夠造。

    但是想像一下吧,如果我們要做一個加法運算,需要先將兩個浮點數轉為String,然后夠造成BigDecimal,在其中一個上調用add方法,傳入另一個作為參數,然后把運算的結果(BigDecimal)再轉換為浮點數。你能夠忍受這么煩瑣的過程嗎?下面我們提供一個工具類Arith來簡化操作。它提供以下靜態方法,包括加減乘除和四舍五入:

    public static double add(double v1, double v2); 
     public static double sub(double v1, double v2); 
     public static double mul(double v1, double v2); 
     public static double div(double v1, double v2); 
     public static double div(double v1, double v2, int scale); 
     public static double round(double v, int scale);
    package org.nutz.mvc.core; 
    import java.math.BigDecimal; 
    public class Arith {
     // 源文件Arith.java:
     
     /**
      * 由于Java的簡單類型不能夠精確的對浮點數進行運算,這個工具類提供精 確的浮點數運算,包括加減乘除和四舍五入。
      */
     
     // 默認除法運算精度
     private static final int DEF_DIV_SCALE = 10;
     
     // 這個類不能實例化
     private Arith() {
     }
     
     /**
      * 提供精確的加法運算。
      * 
      * @param v1
      *            被加數
      * @param v2
      *            加數
      * @return 兩個參數的和
      */
     
     public static double add(double v1, double v2) {
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.add(b2).doubleValue();
     }
     
     /**
      * 提供精確的減法運算。
      * 
      * @param v1
      *            被減數
      * @param v2
      *            減數
      * @return 兩個參數的差
      */
     
     public static double sub(double v1, double v2) {
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.subtract(b2).doubleValue();
     }
     
     /**
      * 提供精確的乘法運算。
      * 
      * @param v1
      *            被乘數
      * @param v2
      *            乘數
      * @return 兩個參數的積
      */
     
     public static double mul(double v1, double v2) {
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.multiply(b2).doubleValue();
     }
     
     /**
      * 提供(相對)精確的除法運算,當發生除不盡的情況時,精確到 小數點以后10位,以后的數字四舍五入。
      * 
      * @param v1
      *            被除數
      * @param v2
      *            除數
      * @return 兩個參數的商
      */
     
     public static double div(double v1, double v2) {
      return div(v1, v2, DEF_DIV_SCALE);
     }
     
     /**
      * 提供(相對)精確的除法運算。當發生除不盡的情況時,由scale參數指 定精度,以后的數字四舍五入。
      * 
      * @param v1
      *            被除數
      * @param v2
      *            除數
      * @param scale
      *            表示表示需要精確到小數點以后幾位。
      * @return 兩個參數的商
      */
     
     public static double div(double v1, double v2, int scale) {
      if (scale < 0) {
       throw new IllegalArgumentException(
         "The   scale   must   be   a   positive   integer   or   zero");
      }
      BigDecimal b1 = new BigDecimal(Double.toString(v1));
      BigDecimal b2 = new BigDecimal(Double.toString(v2));
      return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
     }
     
     /**
      * 提供精確的小數位四舍五入處理。
      * 
      * @param v
      *            需要四舍五入的數字
      * @param scale
      *            小數點后保留幾位
      * @return 四舍五入后的結果
      */
     
     public static double round(double v, int scale) {
      if (scale < 0) {
       throw new IllegalArgumentException(
         "The   scale   must   be   a   positive   integer   or   zero");
      }
      BigDecimal b = new BigDecimal(Double.toString(v));
      BigDecimal one = new BigDecimal("1");
      return b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
     }
    };

    Double相加時出現的多位問題

    String test = "40.61 ,  18588.73,    29925.07,    7986.06,    18639.19,    25914.32,     32907.74,     34165.89,     9724.7,     52777.92";
     String[] arr = test.split(",");
     double sum = 0;
     for(int i=0;i<arr.length;i++){
     sum += Double.parseDouble(arr[i]);
     }
         System.out.println(sum);

    結果: 230670.22999999998

    查了查 沒有深入的了解,大概是java 的double機制,關于精度的問題,若是不出現這種情況,保留小數點后兩位就可以了。或者使用BigDecimal進行計算,另外《effective java》這本書里也提過,double和float 不建議使用商業計算。

    補充:原因在于我們的計算機是二進制的。浮點數沒有辦法是用二進制進行精確表示。

    我們的CPU表示浮點數由兩個部分組成:指數和尾數,這樣的表示方法一般都會失去一定的精確度,有些浮點數運算也會產生一定的誤差。

    如:2.4的二進制表示并非就是精確的2.4。

    反而最為接近的二進制表示是 2.3999999999999999。浮點數的值實際上是由一個特定的數學公式計算得到的。

    到此,關于“Java Double相加出現的問題有哪些”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    柘荣县| 吉林市| 建德市| 都兰县| 禄劝| 平度市| 壶关县| 华坪县| 合山市| 德阳市| 海原县| 滁州市| 梁河县| 五原县| 荥阳市| 礼泉县| 油尖旺区| 新昌县| 娄底市| 班戈县| 基隆市| 银川市| 沾益县| 洛隆县| 临夏市| 南岸区| 东山县| 淳安县| 阜平县| 定安县| 佛坪县| 桂东县| 无为县| 新竹市| 台前县| 育儿| 庆城县| 神农架林区| 海淀区| 汕头市| 定边县|