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萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章