精确的计算方法工具类

该工具类提供了精确的金额计算方法,针对如除法等可能出现的精度问题使用BigDecimal实现精确计算。

 

 

public class NumberUtils {
    private static final int DEF_DIV_SCALE = 10;

    public static int getInt(String s) {
        try {
            return Integer.parseInt(s);
        } catch (Exception e) {
            return 0;
        }
    }

    /**
     * 提供精确的字符串转double
     */
    public static double getDouble(String v) {
        double value = 0.0;
        try {
            BigDecimal b = new BigDecimal(v);
            value = b.doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static double add(double v1, double v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.add(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的加法运算
     *
     * @param v1 被加数
     * @param v2 加数
     * @return 两个参数的和
     */
    public static double add(String v1, String v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            value = b1.add(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double substract(double v1, double v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.subtract(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的减法运算
     *
     * @param v1 被减数
     * @param v2 减数
     * @return 两个参数的差
     */
    public static double substract(String v1, String v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            value = b1.subtract(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double multiply(double v1, double v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));
            value = b1.multiply(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的乘法运算
     *
     * @param v1 被乘数
     * @param v2 乘数
     * @return 两个参数的积
     */
    public static double multiply(String v1, String v2) {
        double value = 0.0;
        try {
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            value = b1.multiply(b2).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供(相对)精确的除法运算,当发生除不尽的情况时,
     * 精确到小数点以后10位以后的数字四舍五入
     *
     * @param v1 被除数
     * @param v2 除数
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2) {
        return divide(v1, v2, DEF_DIV_SCALE);
    }

    /**
     * 提供(相对)精确的除法运算
     * 当发生除不尽的情况时,由scale参数决定精确小数点以后的数字四舍五入
     *
     * @param v1    被除数
     * @param v2    除数
     * @param scale 表示要精确到小数点以后几位
     * @return 两个参数的商
     */
    public static double divide(double v1, double v2, int scale) {
        double value = 0.0;
        try {
            if (scale < 0) {
                return value;
                //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));
            value = b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的小数位四舍五入处理
     *
     * @param v     原四舍五入的数
     * @param scale 小数点后保留几位
     * @return 四舍五入后的结果
     */
    public static double round(double v, int scale) {
        double value = 0.0;
        try {
            if (scale < 0) {
                return value;
               // throw new IllegalArgumentException("The scale must be a positive integer or zero");
            }

            BigDecimal b = new BigDecimal(Double.toString(v));
            BigDecimal one = new BigDecimal("1");
            value = b.divide(one, scale, BigDecimal.ROUND_HALF_UP).doubleValue();
            return value;
        } catch (Exception e) {
            e.printStackTrace();
            return value;
        }
    }

    /**
     * 提供精确的小数位四舍五入处理  默认2
     *
     * @return 四舍五入后的结果
     */
    public static double round(double v) {
        try {
            return round(v, 2);
        } catch (Exception e) {
            return v;
        }
    }

    /**
     * 搜索出输入值最接近的范围内的某一个值
     *
     * @param key 输入的值
     * @param arr 值范围
     * @return 搜索到的索引
     */
    public static double searchNearValue(double key, Double[] arr) {
        //        double[] arr = {1.78, 2.0, 2.08, 2.17}; 1920*1080;2160*1080;2250*1080;2340*1080
        //        double key = 1.82;
        int search = Arrays.binarySearch(arr, key);
        double searchKey = 0.0;
        int index = 0;
        if (search > 0 && search < arr.length) {
            searchKey = arr[search];
            index = search;
        } else if (search == -1) {
            searchKey = arr[0];
            index = 0;
        } else if (search == -(arr.length + 1)) {
            searchKey = arr[arr.length - 1];
            index = arr.length - 1;
        } else if (search < 0 && search >= -arr.length) {
            index = (-2 + Math.abs(search)) > 0 ? (-2 + Math.abs(search)) : 0;
            searchKey = arr[index];
        } else {
            searchKey = arr[0];
            index = 0;
        }
        double needValue = 0.0;
        int nearIndex = 0;
        if (index == arr.length - 1) {
            needValue = arr[arr.length - 1];
            nearIndex = arr.length - 1;
        } else {
            double min = arr[index];
            double max = arr[index + 1];
            if ((key - min) > (max - key)) {
                needValue = max;
                nearIndex = index + 1;
            } else {
                needValue = min;
                nearIndex = index;
            }
        }
        return needValue;
    }

    public static String reserve2Decimals(double d) {
        java.text.DecimalFormat myformat = new java.text.DecimalFormat("0.00");
        return myformat.format(d);
    }

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值