Java提供精确的浮点数运算,包括加减乘除和四舍五入

110 阅读3分钟
public class NumberUtil{
    /**
     * 默认除法运算精度
     */
    private static final int DEF_DIV_SCALE = 10;
    
    /**
     * 转换为保留2位小数 四舍五入
     * 
     * @param number 需要转换的值
     * @return 结果
     */
    public static double twoDecimalPlaces(double number) {
        return Math.round(number * 100) / 100.0;
    }
    
    /**
     * 我才是真正的四舍五入后保留两位小数.包括(1.0 也能变成 1.00)
     * 
     * @param number
     * @return 但是我返回的类型是String
     */
    public static String keepTwoDecimalPlaces(double number){
        DecimalFormat df = new DecimalFormat("0.00");
        return df.format(Math.round(number * 100) / 100.0);
    }
    
    /**
     * 四舍五入保留两位小数 (只转 :为double类型的数字)
     * 
     * @param list
     * @return list
     */
    public static List<Map<String, Object>> keepTwoDecimalPlaces(List<Map<String, Object>> list)  {
        for (Map<String, Object> tempMap : list) {
            for (String key : tempMap.keySet()){
                if (tempMap.get(key) instanceof Double){
                    tempMap.put(key, keepTwoDecimalPlaces((ConverterUtils.toDouble(tempMap.get(key)))));
                }
            }
        }
        return list;
    }
    
    
    /**
     * 提供精确的加法运算。
     * 
     * @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();
    }
    
    /**
     * 提供精确的累加加法运算。
     * 
     * @return 多个参数的和
     */
    public static double add(double... numbers) {
        double resultDouble = 0.0;
        int length = numbers.length;
        if (length == 1) {
            resultDouble = numbers[0];
        } else if (length > 1) {
            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(numbers[0]));
            for (int i = 0; i < length - 1; i++){
                BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(numbers[i + 1]));
                bigDecimal1 = bigDecimal1.add(bigDecimal2);
            }
            resultDouble = bigDecimal1.doubleValue();
        }
        return resultDouble;
    }
    
    /**
     * 提供精确的减法运算。
     * 
     * @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();
    }
    
    /**
     * 提供精确的累减减法运算。
     * 
     * @return 参数顺序不能填错
     */
    public static double sub(double... numbers){
        double resultDouble = 0.0;
        int length = numbers.length;
        if (length == 1) {
            resultDouble = numbers[0];
        }else if (length > 1) {
            BigDecimal bigDecimal1 = new BigDecimal(String.valueOf(numbers[0]));
            for (int i = 0; i < length - 1; i++){
                BigDecimal bigDecimal2 = new BigDecimal(String.valueOf(numbers[i + 1]));
                bigDecimal1 = bigDecimal1.subtract(bigDecimal2);
            }
            resultDouble = bigDecimal1.doubleValue();
        }
        return resultDouble;
    }
    
    /**
     * 提供精确的乘法运算。
     * 
     * @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();
    }
    
    /**
     * @description:提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍不入。
     * @param v1
     * @param v2
     * @param scale
     * @return double
     */
    public static double divDown(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_DOWN).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();
    }
    
    /**
     * 提供精确的小数位四舍五不入处理。
     * 
     * @param v 需要四舍五不入的数字
     * @param scale 小数点后保留几位
     * @return 四舍五不入后的结果
     */
    public static double numberDown(double v, int scale) {
        return new BigDecimal(ConverterUtils.toString(v)).setScale(scale,BigDecimal.ROUND_DOWN).doubleValue();
    }
    
    /**
     * @description:四舍五入把double转化int整型,0.5进一,小于0.5不进一
     * @param number 
     * @return int
     */
    public static int getInt(double number){
        BigDecimal bd=new BigDecimal(number).setScale(0, BigDecimal.ROUND_HALF_UP);
        return Integer.parseInt(bd.toString());
    }