zoukankan      html  css  js  c++  java
  • Java中double相减精度的问题,和解决方法

    问题原因原帖1 

    解决方法:

    使用BigDecimal方法来解决。

    BigDecimal原理是什么?为什么它就没事?原理很简单。BigDecimal是不可变的,可以用来表示任意精度的带符号十进制数。double的问题是从小数点转换到二进制丢失精度,二进制丢失精度。BigDecimal在处理的时候把十进制小数扩大N倍让它在整数上进行计算,并保留相应的精度信息。至于BigDecimal是怎么保存的可以翻阅一下源代码。

    /**
     * double的计算不精确,会有类似0.0000000000000002的误差,正确的方法是使用BigDecimal或者用整型
     * 整型地方法适合于货币精度已知的情况,比如12.11+1.10转成1211+110计算,最后再/100即可
     * 以下是摘抄的BigDecimal方法:
     */
     public class DoubleUtils implements Serializable {
         private static final long serialVersionUID = -3345205828566485102L;
         // 默认除法运算精度
         private static final Integer DEF_DIV_SCALE = 2;
    
         /**
          * 提供精确的加法运算。
         *
          * @param value1 被加数
          * @param value2 加数
        * @return 两个参数的和
        */
        public static Double add(Double value1, Double value2) {
             BigDecimal b1 = new BigDecimal(Double.toString(value1));
             BigDecimal b2 = new BigDecimal(Double.toString(value2));
             return b1.add(b2).doubleValue();
        }
    
        /**
          * 提供精确的减法运算。
          *
          * @param value1 被减数
          * @param value2 减数
          * @return 两个参数的差
          */
         public static double sub(Double value1, Double value2) {
             BigDecimal b1 = new BigDecimal(Double.toString(value1));
            BigDecimal b2 = new BigDecimal(Double.toString(value2));
            return b1.subtract(b2).doubleValue();
        }
    
        /**
         * 提供精确的乘法运算。
         *
          * @param value1 被乘数
          * @param value2 乘数
         * @return 两个参数的积
         */
         public static Double mul(Double value1, Double value2) {
            BigDecimal b1 = new BigDecimal(Double.toString(value1));
             BigDecimal b2 = new BigDecimal(Double.toString(value2));
            return b1.multiply(b2).doubleValue();
       }
        /**
        * 提供(相对)精确的除法运算,当发生除不尽的情况时, 精确到小数点以后10位,以后的数字四舍五入。
        *
        * @param dividend 被除数
        * @param divisor  除数
        * @return 两个参数的商
        */
         public static Double divide(Double dividend, Double divisor) {
            return divide(dividend, divisor, DEF_DIV_SCALE);
        }
    
         /**
        * 提供(相对)精确的除法运算。 当发生除不尽的情况时,由scale参数指定精度,以后的数字四舍五入。
        *
        * @param dividend 被除数
        * @param divisor  除数
        * @param scale    表示表示需要精确到小数点以后几位。
        * @return 两个参数的商
        */
         public static Double divide(Double dividend, Double divisor, Integer scale) {
            if (scale < 0) {
                throw new IllegalArgumentException("The scale must be a positive integer or zero");
            }
           BigDecimal b1 = new BigDecimal(Double.toString(dividend));
          BigDecimal b2 = new BigDecimal(Double.toString(divisor));
             return b1.divide(b2, scale,RoundingMode.HALF_UP).doubleValue();
        }
    
     /**
       * 提供指定数值的(精确)小数位四舍五入处理。
       *
       * @param value 需要四舍五入的数字
       * @param scale 小数点后保留几位
       * @return 四舍五入后的结果
       */
        public static double round(double value,int scale){
             if(scale<0){
               throw new IllegalArgumentException("The scale must be a positive integer or zero");
             }
             BigDecimal b = new BigDecimal(Double.toString(value));
           BigDecimal one = new BigDecimal("1");
            return b.divide(one,scale, RoundingMode.HALF_UP).doubleValue();
         }
     }
  • 相关阅读:
    Truck History(poj 1789)
    Highways poj 2485
    117. Populating Next Right Pointers in Each Node II
    116. Populating Next Right Pointers in Each Node
    115. Distinct Subsequences
    114. Flatten Binary Tree to Linked List
    113. Path Sum II
    109. Convert Sorted List to Binary Search Tree
    106. Construct Binary Tree from Inorder and Postorder Traversal
    105. Construct Binary Tree from Preorder and Inorder Traversal
  • 原文地址:https://www.cnblogs.com/MoonASixpence/p/14799847.html
Copyright © 2011-2022 走看看