BigDecimal 工具类

package com.knowledge.system.bigdecimalutil;

import java.math.BigDecimal;

/**
 * @program: demo-pom
 * @description: BigDecimal工具类
 * @author: bo.hu
 * @create: 2020-01-14 17:23
 **/
public class BigdcmUtil {

    /**
     *                    BigDecimal.ROUND_HALF_UP     四舍五入
     *                    BigDecimal.ROUND_HALF_DOWN   五舍六入
     *                    BigDecimal.ROUND_HALF_EVEN   四舍六入,五分两种情况,前一位为奇数,则入位,否则舍去。
     *
     *                    BigDecimal.ROUND_DOWN        直接舍弃      ----此舍入模式始终不会增加计算值的大小
     *                                                 -3.559->-3.55   -3.551->-3.55  3.559->3.55   3.551->3.55
     *
     *                    BigDecimal.ROUND_UP          非零直接进位  ----此舍入模式始终不会减少计算值的大小
     *                                                 -3.550->-3.55  -3.559->-3.56   -3.551->-3.56    3.550->3.55  3.559->3.56   3.551->3.56
     *
     *                    BigDecimal.ROUND_CEILING     正--BigDecimal.ROUND_UP,负数--BigDecimal.ROUND_DOWN  ----此舍入模式始终不会减少计算值
     *                                                 -3.550->-3.55  -3.559->-3.55   -3.551->-3.55    3.550->3.55  3.559->3.56   3.551->3.56
     *
     *                    BigDecimal.ROUND_FLOOR       正--BigDecimal.ROUND_DOWN,负数--BigDecimal.ROUND_UP  ----此舍入模式始终不会增加计算值
     *                                                 -3.550->-3.55  -3.559->-3.56   -3.551->-3.56    3.550->3.55  3.559->3.55   3.551->3.55
     *
     *                    BigDecimal.ROUND_UNNECESSARY 断言请求的操作具有精确的结果,因此不需要舍入。如果对获得精确结果的操作指定此舍入模式,则抛出ArithmeticException。【一般不用】
     *
     */

    /**
     * 金额简单处理       分转元
     *
     * @param n1        待处理金额
     * @param scale     保留小数位数
     * @param remainder 尾数处理方式
     * @return
     */
    public static BigDecimal getY2F(String n1,int scale,int remainder){
        if(null==n1){
            return null;
        }
        BigDecimal num1=new BigDecimal(n1);
        return num1.multiply(new BigDecimal("100.00")).setScale(scale,remainder);
    }

    /**
     * 金额简单处理       分转元
     *
     * @param n1        待处理金额
     * @param scale     保留小数位数
     * @param remainder 尾数处理方式
     * @return
     */
    public static BigDecimal getF2Y(String n1, int scale, int remainder) {
        if (null == n1) {
            return null;
        }
        BigDecimal num1 = new BigDecimal(n1);
        return num1.divide(new BigDecimal("100.00"), scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getChangeRatio(double n1, double n2, int scale, int remainder) {
        String num1 = Double.toString(n1);
        String num2 = Double.toString(n2);
        return getChangeRatio(num1, num2, scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getChangeRatio(long n1, long n2, int scale, int remainder) {
        String num1 = Long.toString(n1);
        String num2 = Long.toString(n2);
        return getChangeRatio(num1, num2, scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getChangeRatio(int n1, int n2, int scale, int remainder) {
        String num1 = Integer.toString(n1);
        String num2 = Integer.toString(n2);
        return getChangeRatio(num1, num2, scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getChangeRatio(String n1, String n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal v1 = new BigDecimal(n1);
        BigDecimal v2 = new BigDecimal(n2);
        return getChangeRatio(v1, v2, scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getChangeRatio(BigDecimal n1, BigDecimal n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal v1 = n1.subtract(n2);
        return getRatio(v1, n2, scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getRatio(long n1, long n2, int scale, int remainder) {
        String str1 = Long.toString(n1);
        String str2 = Long.toString(n2);
        return getRatio(str1, str2, scale, remainder);
    }

    /**
     * 求变化率
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getRatio(int n1, int n2, int scale, int remainder) {
        String str1 = Integer.toString(n1);
        String str2 = Integer.toString(n2);
        return getRatio(str1, str2, scale, remainder);
    }

    /**
     * @param d1        除数
     * @param d2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getRatio(double d1, double d2, int scale, int remainder) {
        String str1 = Double.toString(d1);
        String str2 = Double.toString(d2);
        return getRatio(str1, str2, scale, remainder);
    }

    /**
     * 求百分比
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getRatio(String n1, String n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal v1 = new BigDecimal(n1);
        BigDecimal v2 = new BigDecimal(n2);
        return getRatio(v1, v2, scale, remainder);
    }

    /**
     * 求百分比
     *
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数尾数处理方法
     * @return
     */
    public static BigDecimal getRatio(BigDecimal n1, BigDecimal n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        if (0 == n2.compareTo(BigDecimal.ZERO)) {
            return new BigDecimal(1).setScale(scale);
        }
        return n1.divide(n2, scale, remainder);
    }

    /**
     * 求两数和
     *
     * @param n1        加数1
     * @param n2        加数2
     * @param scale     保留小数位数
     * @param remainder 小数位数处理方法
     * @return
     */
    public static BigDecimal add(String n1, String n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal num1 = new BigDecimal(n1);
        BigDecimal num2 = new BigDecimal(n2);
        return (num1.add(num2)).setScale(scale, remainder);
    }

    /**
     * 求两数差
     *
     * @param n1        减数
     * @param n2        被减数
     * @param scale     保留小数位数
     * @param remainder 小数位数处理方法
     * @return
     */
    public static BigDecimal sub(String n1, String n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal num1 = new BigDecimal(n1);
        BigDecimal num2 = new BigDecimal(n2);
        return num1.subtract(num2).setScale(scale, remainder);
    }

    /**
     * 求两数积
     *
     * @param n1        乘数1
     * @param n2        乘数2
     * @param scale     保留小数位数
     * @param remainder 小数位数处理方法
     * @return
     */
    public static BigDecimal mul(String n1, String n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal num1 = new BigDecimal(n1);
        BigDecimal num2 = new BigDecimal(n2);
        return num1.multiply(num2).setScale(scale, remainder);
    }

    /**
     * @param n1        除数
     * @param n2        被除数
     * @param scale     保留小数位数
     * @param remainder 小数位数处理方法
     * @return
     */
    public static BigDecimal div(String n1, String n2, int scale, int remainder) {
        if (null == n1 || null == n2) {
            return null;
        }
        BigDecimal num1 = new BigDecimal(n1);
        BigDecimal num2 = new BigDecimal(n2);
        if (0 == num2.compareTo(BigDecimal.ZERO)) {
            throw new RuntimeException("除数不能为零");
        }
        return num1.divide(num2, scale, remainder);
    }

    /**
     * 设置参数小数位数
     *
     * @param n1        参数
     * @param scale     小数点位数
     * @param remainder 尾数处理方式
     * @return
     */
    public static BigDecimal setPoint(String n1, int scale, int remainder) {
        if (null == n1) {
            return null;
        }
        BigDecimal num1 = new BigDecimal(n1);
        return num1.setScale(scale, remainder);
    }

    /**
     * 设置参数小数位数
     *
     * @param n1        参数
     * @param scale     小数点位数
     * @param remainder 尾数处理方式
     * @return
     */
    public static BigDecimal setPoint(int n1, int scale, int remainder) {
        String num1 = Integer.toString(n1);
        return setPoint(num1, scale, remainder);
    }

    /**
     * 设置参数小数位数
     *
     * @param n1        参数
     * @param scale     小数点位数
     * @param remainder 尾数处理方式
     * @return
     */
    public static BigDecimal setPoint(long n1, int scale, int remainder) {
        String num1 = Long.toString(n1);
        return setPoint(num1, scale, remainder);
    }

    /**
     * 设置参数小数位数
     *
     * @param n1        参数
     * @param scale     小数点位数
     * @param remainder 尾数处理方式
     * @return
     */
    public static BigDecimal setPoint(double n1, int scale, int remainder) {
        String num1 = Double.toString(n1);
        return setPoint(num1, scale, remainder);
    }

    /**
     * 比较大小,flag取值:==:1  <:2   >:3   <=:4   >=:5   !=:6
     *
     * @param n1
     * @param n2
     * @param flag
     * @return
     */
    public static boolean compare(String n1, String n2, int flag) {
        if (null == n1 || null == n2 || n1.equals("") || n2.equals("")) {
            return false;
        }
        BigDecimal num1Bcm1 = new BigDecimal(n1);
        BigDecimal num2Bcm2 = new BigDecimal(n2);
        if (1 == flag) {
            return num1Bcm1.compareTo(num2Bcm2) == 0;
        }
        if (2 == flag) {
            return num1Bcm1.compareTo(num2Bcm2) == -1;
        }
        if (3 == flag) {
            return num1Bcm1.compareTo(num2Bcm2) == 1;
        }
        if (4 == flag) {
            return num1Bcm1.compareTo(num2Bcm2) <= 0;
        }
        if (5 == flag) {
            return num1Bcm1.compareTo(num2Bcm2) >= 0;
        }
        if (6 == flag) {
            return !(num1Bcm1.compareTo(num2Bcm2) == 0);
        }
        return false;
    }

    public static void main(String[] args) {

        /**
         * 为什么要使用BigDecimal   深坑1:9.86->9.85     1219.86->121985   精度问题
         */
        //+++++++++++Float Double带来的---精度问题++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        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.06元,却无法购买一个0.05元和一个0.01元的商品。因为如上所示,他们两个的总和为0.060000000000000005。
        //float和double只能用来做科学计算和工程计算。商业运算中我们要使用BigDecimal。

        //++++++++++++BigDecimal因为创建方式而带来的---精度问题+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
        BigDecimal d1 = new BigDecimal(0.6);
        BigDecimal d2 = new BigDecimal(0.4);
        //        BigDecimal d3=d1.divide(d2);//除不尽,精度未设置,导致异常
        BigDecimal d7 = d1.divide(d2, 2, BigDecimal.ROUND_HALF_UP);

        BigDecimal d4 = new BigDecimal("0.600000");//构造完,自带精度6
        BigDecimal d5 = new BigDecimal("4");
        BigDecimal d6 = d4.divide(d5);
        System.out.println(d6);
        System.out.println(d7);
        //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

        //+++++++++++++++++商业解决方案:1.无论使用哪种方式创建对象,均指定计算完成后的精度++++++++++++++++++++
        //+++++++++++++++++商业解决方案:与之配套的数据库字段设计方案++++++++++++++++++++
        //+++++++++++++++++`balance` decimal(18,2) DEFAULT '0.00' COMMENT '账户余额'  默认值一定设置成0.00以免排序时带来类型转换的麻烦
        BigDecimal dT1 = new BigDecimal(0.6);
        BigDecimal dT2 = new BigDecimal(0.4);
        BigDecimal dT3 = dT1.divide(dT2, 2, BigDecimal.ROUND_HALF_UP);
    }
}

 

发布了78 篇原创文章 · 获赞 25 · 访问量 6万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章