BigDecimal工具类和Java数字处理

package org.lee.study.utils;

import java.math.BigDecimal;

/**
 * 用于高精度的数学运算
 * 1.加减乘除
 * 2.四舍五入
 * 3.比较大小
 *
 * BigDecimal类:
 * 优点:适合精确的小数点计算。
 * 缺点:性能差。
 * 使用:开发过程一般使用String的构造函数。
 * @author lee
 * @date 2022/4/21 14:25
 */
public class ArithmeticUtils {
    private static final int DEF_DIV_SCALE = 10;

    /**
     * double类型的加法运算(不会丢失精度)
     * 通过源码可知,String.valueOf(double d)等同于Double.toString(d);
     * @param v1 被加数
     * @param v2 加数
     * @return 相加之和
     */
    public static double add(double v1, double v2){
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.add(b2).doubleValue();
    }

    /**
     * String类型的加法运算(不会丢失精度)
     * @param v1 被加数
     * @param v2 加数
     * @return 相加之和
     */
    public static BigDecimal add(String v1, String v2){
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2);
    }

    /**
     * String类型保留小数点的加法运算
     * BigDecimal.ROUND_HALF_UP等同于四舍五入
     * @param v1 被加数
     * @param v2 加数
     * @param scale 保留小数点位数
     * @return 相加之和 subtraction
     */
    public static String add(String v1, String v2, int scale){
        if(scale < 0){
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.add(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * double类型的减法运算(不会丢失精度)
     * @param v1 被减数
     * @param v2 减数
     * @return 相减之差
     */
    public static double subtraction(double v1, double v2){
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.subtract(b2).doubleValue();
    }

    /**
     * String类型的减法运算(不会丢失精度)
     * @param v1 被减数
     * @param v2 减数
     * @return 相减之差
     */
    public static BigDecimal subtraction(String v1, String v2){
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2);
    }

    /**
     * String类型保留小数点的减法运算
     * BigDecimal.ROUND_HALF_UP等同于四舍五入
     * @param v1 被减数
     * @param v2 减数
     * @param scale 保留小数点位数
     * @return 相减之差
     */
    public static String subtraction(String v1, String v2, int scale){
        if(scale < 0){
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.subtract(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * double类型的乘法运算(不会丢失精度)
     * @param v1 乘数
     * @param v2 乘数
     * @return 乘积
     */
    public static double multiplication(double v1, double v2){
        BigDecimal b1 = new BigDecimal(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.multiply(b2).doubleValue();
    }

    /**
     * String类型的乘法运算(不会丢失精度)
     * @param v1 乘数
     * @param v2 乘数
     * @return 乘积
     */
    public static BigDecimal multiplication(String v1, String v2){
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2);
    }

    /**
     * String类型保留小数点的乘法运算
     * BigDecimal.ROUND_HALF_UP等同于四舍五入
     * @param v1 乘数
     * @param v2 乘数
     * @param scale 保留小数点位数
     * @return 乘积
     */
    public static String multiplication(String v1, String v2, int scale){
        if(scale < 0){
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.multiply(b2).setScale(scale,BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * double类型保留小数点的除法运算
     * @param v1 被除数
     * @param v2 除数
     * @return 商
     */
    private static double division(double v1, double v2){
        return division(v1,v2,DEF_DIV_SCALE);
    }

    /**
     * double类型保留小数点的除法运算
     * @param v1 被除数
     * @param v2 除数
     * @param scale 保留的小数点数
     * @return 商
     */
    public static double division(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(String.valueOf(v1));
        BigDecimal b2 = new BigDecimal(String.valueOf(v2));
        return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).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(String.valueOf(v));
        return b.setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();
    }

    /**
     * 四舍五入处理
     * @param v 需要四舍五入的值
     * @param scale 保留小数点的位数
     * @return 四舍五入后的值
     */
    public static String round(String v, int scale){
        if(scale < 0){
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b = new BigDecimal(v);
        return b.setScale(scale,BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 取余数
     * @param v1 被除数
     * @param v2 除数
     * @param scale 保留小数点的位数
     * @return 余数
     */
    public static String remainder(String v1, String v2, int scale){
        if(scale < 0){
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        return b1.remainder(b2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 取余数
     * @param v1 被除数
     * @param v2 除数
     * @param scale 保留小数点的位数
     * @return 余数
     */
    public static String remainder(BigDecimal v1, BigDecimal v2, int scale){
        if(scale < 0){
            throw new IllegalArgumentException("The scale must be a positive integer or zero");
        }
        return v1.remainder(v2).setScale(scale, BigDecimal.ROUND_HALF_UP).toString();
    }

    /**
     * 比较大小
     * a = -1,表示v1小于v2
     * a = 0,表示v1等于v2
     * a = 1,表示v1大于v2
     * @param v1 被比较数
     * @param v2 比较数
     * @return 比较结果 true or false 如果v1大于v2,则返回true,否则返回false
     */
    public static boolean compare(String v1, String v2){
        BigDecimal b1 = new BigDecimal(v1);
        BigDecimal b2 = new BigDecimal(v2);
        int bj = b1.compareTo(b2);
        boolean res;
        if(bj>0) {
            res = true;
        }
        else {
            res = false;
        }
        return res;
    }
}
package org.lee.study;

import java.math.BigDecimal;
import java.text.NumberFormat;

/**
 * @author lee
 * @date 2022/4/21 15:26
 */
public class BigDecimalDemo {
    public static void main(String[] args) {
        NumberFormat currency = NumberFormat.getCurrencyInstance();
        //送参数指定国家币种 Locale.FRANCE,默认是人民币
        NumberFormat percent = NumberFormat.getPercentInstance();
        percent.setMaximumFractionDigits(3);

        BigDecimal loanAmount = new BigDecimal("15000.48");
        BigDecimal interestRate = new BigDecimal("0.008");
        BigDecimal interest = loanAmount.multiply(interestRate);

        System.out.println("贷款金额:\t" + currency.format(loanAmount));
        System.out.println("利率:\t" + percent.format(interestRate));
        System.out.println("利息:\t" + currency.format(interest));
    }
}
package org.lee.study.utils;

import java.text.DecimalFormat;
import java.text.NumberFormat;

/**
 * @author lee
 * @date 2022/4/21 15:43
 */
public class NumberDealUtils {
    /**
     * 移除数字前面和后面冗余的0,只保留3位小数
     *
     * @param isFormat 是否需要千位分隔符(,)这种格式输出
     * @param num 被处理的数字
     * @return 被处理的数字
     */
    public static String trimZero(boolean isFormat, double num) {
        NumberFormat nf = NumberFormat.getInstance();
        if (!isFormat) {
            //设置输出格式是否使用“,”分组,默认是使用的
            nf.setGroupingUsed(false);
        }
        return nf.format(num);
    }

    /**
     * 移除数字前面和后面冗余的0
     *
     * @param isFormat      是否需要千位分隔符(,)这种格式输出
     * @param num 被处理的数字
     * @param fractionDigit 要保留的小数位数
     * @return 被处理的数字
     */
    public static String trimZero(boolean isFormat, double num, int fractionDigit) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(fractionDigit);
        if (!isFormat) {
            //设置输出格式是否使用“,”分组,默认是使用的
            nf.setGroupingUsed(false);
        }
        return nf.format(num);
    }

    /**
     * 指定位数输出,不足补0
     * 整数部分如果位数大于需要的位数按实际位数输出
     * 小数部分如果大于需要的位数四舍五入
     *
     * @param num 被处理的数字
     * @param integerDigit  整数部分位数
     * @param fractionDigit 小数部分位数
     * @return 被处理的数字
     */
    public static String addZeroFormat(double num, int integerDigit, int fractionDigit) {
        StringBuilder rule = new StringBuilder();
        if (integerDigit <= 0) {
            rule.append("#");
        } else {
            for (int i = 0; i < integerDigit; i++) {
                rule.append("0");
            }
        }
        if (fractionDigit > 0) {
            rule.append(".");
            for (int i = 0; i < fractionDigit; i++) {
                rule.append("0");
            }
        }
        DecimalFormat df = new DecimalFormat(rule.toString());
        return df.format(num);
    }

    /**
     * 保留几位小数,不足不补0,小数部分冗余的0也不显示
     *
     * @param num 被处理的数字
     * @param fractionDigit 要保留小数的位数
     * @return 被处理的数字
     */
    public static String fractionDigitFormat(double num, int fractionDigit) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(fractionDigit);
        //设置输出格式是否使用“,”分组,这里不使用
        nf.setGroupingUsed(false);
        return nf.format(num);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值