JAVA工具类之BigDecimal精确计算

MathExtend.java

package com.bigbigbu.cf.common.utils;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.text.ParseException;

/**
* @Title: MathExtend
* @Description: 精确计算
* @Company: 卜凡起的博客
* @author    FANQIBU
* @date       2018年2月2日
*/
public class MathExtend {

        // 默认除法运算精度
        public static final int DEFAULT_DIV_SCALE_2 = 2;
        public static final int DEFAULT_DIV_SCALE_4 = 4;

        public static String formatDouble(double dValue,String formatStr){
            DecimalFormat mformat = new DecimalFormat(formatStr); 
            return mformat.format(dValue);
        }

        /**
         * 提供精确的加法运算。
         * 
         * @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 String add(String v1, String v2) {
            if(StringUtils.checkEmpty(v1)) v1="0";
            if(StringUtils.checkEmpty(v2)) v2="0";

            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            return b1.add(b2).toString();
        }

        /**
         * 提供精确的减法运算。
         * 
         * @param v1
         * @param v2
         * @return 两个参数的差
         */
        public static double subtract(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 String subtract(String v1, String v2) {
            if(StringUtils.checkEmpty(v1)) v1="0";
            if(StringUtils.checkEmpty(v2)) v2="0";

            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            return b1.subtract(b2).toString();
        }

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

        /**
         * 提供精确的乘法运算
         * 
         * @param v1
         * @param v2
         * @return 两个参数的数学积,以字符串格式返回
         */
        public static String multiply(String v1, String v2) {
            if(StringUtils.checkEmpty(v1)) v1="0";
            if(StringUtils.checkEmpty(v2)) v2="0";

            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);
            return b1.multiply(b2).toString();
        }

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

        /**
         * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
         * 
         * @param v1
         * @param v2
         * @param scale
         *            表示需要精确到小数点以后几位。
         * @return 两个参数的商
         */
        public static double divide(double v1, double v2, int scale) {
            return divide(v1, v2, scale, BigDecimal.ROUND_HALF_EVEN);
        }

        /**
         * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
         * 
         * @param v1
         * @param v2
         * @param scale
         *            表示需要精确到小数点以后几位
         * @param round_mode
         *            表示用户指定的舍入模式
         * @return 两个参数的商
         */
        public static double divide(double v1, double v2, int scale, int round_mode) {
            if (scale < 0) {
                throw new IllegalArgumentException("精度指定错误,请指定一个>=0的精度");
            }
            BigDecimal b1 = new BigDecimal(Double.toString(v1));
            BigDecimal b2 = new BigDecimal(Double.toString(v2));

            double d=0.0;
            try{
                d=b1.divide(b2, scale, round_mode).doubleValue();
            }catch (ArithmeticException e) {
//              e.printStackTrace();
                d=0.0;
                throw new ArithmeticException("被除数不能为0!");
            }
            return d;
        }

        /**
         * 提供(相对)精确的除法运算,当发生除不尽的情况时,精确到 小数点以后10位,以后的数字四舍五入,舍入模式采用ROUND_HALF_EVEN
         * 
         * @param v1
         * @param v2
         * @return 两个参数的商,以字符串格式返回
         */
        public static String divide(String v1, String v2) {
            if(StringUtils.checkEmpty(v1)) v1="0";

            return divide(v1, v2, DEFAULT_DIV_SCALE_2);
        }

        /**
         * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用ROUND_HALF_EVEN
         * 
         * @param v1
         * @param v2
         * @param scale
         *            表示需要精确到小数点以后几位
         * @return 两个参数的商,以字符串格式返回
         */
        public static String divide(String v1, String v2, int scale) {
            if(StringUtils.checkEmpty(v1)) v1="0";

            return divide(v1, v2, DEFAULT_DIV_SCALE_2, BigDecimal.ROUND_HALF_EVEN);
        }

        /**
         * 提供(相对)精确的除法运算。当发生除不尽的情况时,由scale参数指 定精度,以后的数字四舍五入。舍入模式采用用户指定舍入模式
         * 
         * @param v1
         * @param v2
         * @param scale
         *            表示需要精确到小数点以后几位
         * @param round_mode
         *            表示用户指定的舍入模式
         * @return 两个参数的商,以字符串格式返回
         */
        public static String divide(String v1, String v2, int scale, int round_mode) {
            if(StringUtils.checkEmpty(v1)) v1="0";

            if (scale < 0) {
                throw new IllegalArgumentException("精度指定错误,请指定一个>=0的精度");
            }
            BigDecimal b1 = new BigDecimal(v1);
            BigDecimal b2 = new BigDecimal(v2);

            BigDecimal d=new BigDecimal(0);
            try{
                d=b1.divide(b2, scale, round_mode);
            }catch (ArithmeticException e) {
                    d=new BigDecimal(0);
                    e.printStackTrace();
                    throw new ArithmeticException("被除数不能为0!");
            }
            return d.toString();

        }

        /**
         * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
         * 
         * @param v
         *            需要四舍五入的数字
         * @param scale
         *            小数点后保留几位
         * @return 四舍五入后的结果
         */
        public static double round(double v, int scale) {
            return round(v, scale, BigDecimal.ROUND_HALF_EVEN);
        }

        /**
         * 提供精确的小数位四舍五入处理
         * 
         * @param v
         *            需要四舍五入的数字
         * @param scale
         *            小数点后保留几位
         * @param round_mode
         *            指定的舍入模式
         * @return 四舍五入后的结果
         */
        public static double round(double v, int scale, int round_mode) {
            if (scale < 0) {
                throw new IllegalArgumentException("精度指定错误,请指定一个>=0的精度");
            }
            BigDecimal b = new BigDecimal(Double.toString(v));
            return b.setScale(scale, round_mode).doubleValue();
        }

        /**
         * 提供精确的小数位四舍五入处理,舍入模式采用ROUND_HALF_EVEN
         * 
         * @param v
         *            需要四舍五入的数字
         * @param scale
         *            小数点后保留几位
         * @return 四舍五入后的结果,以字符串格式返回
         */
        public static String round(String v, int scale) {
            if(StringUtils.checkEmpty(v)) v="0";

            return round(v, scale, BigDecimal.ROUND_HALF_EVEN);
        }

        /**
         * 提供精确的小数位四舍五入处理
         * 
         * @param v
         *            需要四舍五入的数字
         * @param scale
         *            小数点后保留几位
         * @param round_mode
         *            指定的舍入模式
         * @return 四舍五入后的结果,以字符串格式返回
         */
        public static String round(String v, int scale, int round_mode) {
            if(StringUtils.checkEmpty(v)) v="0";
            if (scale < 0) {
                throw new IllegalArgumentException("精度指定错误,请指定一个>=0的精度");
            }
            BigDecimal b = new BigDecimal(v);
            return b.setScale(scale, round_mode).toString();
        }

        /**
         * 将数字格式的字符串里面,有逗号去掉
         * @param str=3,000.00
         * @return 将包含逗号的字符去掉
         */
        public static String parseDouStr(String str) throws ParseException {
            DecimalFormatSymbols dfs = new DecimalFormatSymbols();  
            dfs.setDecimalSeparator('.');  
            dfs.setGroupingSeparator(',');  
            dfs.setMonetaryDecimalSeparator('.');  
            DecimalFormat df = new DecimalFormat("###,###.##",dfs);  

            Number num = df.parse(str);  
            return num.toString();
        }
        /**
        * @Title: numTwo 
        * @Description:保留两位小数(向上取) 
        * @Author:hxy
        * @param @param str
        * @param @return
        * @return String
        * @throws
         */
        public static String numTwo(String str) {
            if(StringUtils.checkEmpty(str)) str="0";
            BigDecimal b = new BigDecimal(str);
            return b.setScale(2, BigDecimal.ROUND_FLOOR).toString();
        }
}

你可能感兴趣的:(JAVASE)