BigDecimal常用方法及手写通用工具类

刚学Java时我们会用float和double来做带小数的数值计算,但它俩只能用来做科学计算或者是工程计算(会有进度丢失问题)。如果对精度要求高,比如项目中计算金额、计算用水量用电量、计算住房面积时,我们需要使用Java在java.math包中提供的BigDecimal类。但BigDecimal是一个对象,不能像float和double直接进行加减乘除的计算,需要使用它提供的内置方法计算。

我在项目中写的一个操作BigDecimal的工具类:

package com.xxx.util;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Objects;

/**
 * BigDecimal工具类
 * 
 * 加法 add()
 * 减法 subtract()
 * 乘法 multiply()
 * 除法 divide()
 * 精度 setScale()
 * 绝对值 abs()
 *
 * @Author wanglingqiang
 * @Date 2021/9/15 14:39
 */
public class BigDecimalUtil {

    private static final BigDecimal BigDecimal_ZERO = new BigDecimal("0.00");

    /**
     * 判断是否为空或0
     *
     * @param arg
     * @return
     */
    public static boolean isEmpty(BigDecimal arg) {
        if (Objects.isNull(arg) || BigDecimal.ZERO.equals(arg) || BigDecimal_ZERO.equals(arg)) {
            return true;
        }
        return false;
    }

    /**
     * 乘法(精确小数点后2位、四舍五入)
     *
     * @param arg1
     * @param arg2
     * @return
     */
    public static BigDecimal multiply(BigDecimal arg1, BigDecimal arg2) {
        if (isEmpty(arg1) || isEmpty(arg2)) {
            return BigDecimal.ZERO;
        }
        return arg1.multiply(arg2).setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 除法(精确小数点后2位、四舍五入)
     *
     * @param arg1
     * @param arg2
     * @return
     */
    public static BigDecimal divide(BigDecimal arg1, BigDecimal arg2) {
        if (isEmpty(arg1) || isEmpty(arg2)) {
            return BigDecimal.ZERO;
        }
        return BigDecimalUtil.divide(arg1, arg2, 2);
    }

    /**
     * 除法(四舍五入)
     *
     * @param arg1
     * @param arg2
     * @param scale 精确几位数
     * @return
     */
    public static BigDecimal divide(BigDecimal arg1, BigDecimal arg2, int scale) {
        if (isEmpty(arg1) || isEmpty(arg2)) {
            return BigDecimal.ZERO;
        }
        return arg1.divide(arg2, scale, RoundingMode.HALF_UP);
    }

    /**
     * 返回值,精确小数点后2位、四舍五入
     *
     * @param arg
     * @return
     */
    public static BigDecimal valueOf(BigDecimal arg) {
        if (isEmpty(arg)) {
            return BigDecimal.ZERO;
        }
        return arg.setScale(2, RoundingMode.HALF_UP);
    }

    /**
     * 比较两个值的大小
     * arg1 > arg2 返回1
     * arg1 < arg2 返回-1
     * arg1 == arg2 返回0
     *
     * @param arg1
     * @param arg2
     * @return
     */
    public static int compare(BigDecimal arg1, BigDecimal arg2) {
        if (isEmpty(arg1) || isEmpty(arg2)) {
            throw new NullPointerException();
        }
        return arg1.compareTo(arg2);
    }

    private BigDecimalUtil() {
    }
    
}

注意对BigDecimal做除法时,一定要设置精确的小数点。不然会报错Exception in thread “main” java.lang.ArithmeticException: Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1693)
at com.crdigital.intelligent.park.modules.api.utils.ParkMapping.main(ParkMapping.java:104)

在这里插入图片描述
报错原因是不能整除,结果0.3333333……无限长。设置除法四舍五入且精确小数点后两位后,报错解决。
在这里插入图片描述


Java的BigDecimal类型在MySQL中对应的是decimal类型。比如:

CREATE TABLE `pay_record` (
  `id` varchar(64) NOT NULL COMMENT '主键ID',
  `pay_no` varchar(64) DEFAULT NULL COMMENT '支付编号',
  `pay_user` varchar(64) DEFAULT NULL COMMENT '支付人',
  `amount` decimal(18,2) DEFAULT '0.00' COMMENT '支付金额',
  `remark` varchar(255) DEFAULT NULL COMMENT '备注',
  `create_by` varchar(64) DEFAULT NULL COMMENT '创建人',
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_by` varchar(64) DEFAULT NULL COMMENT '更新人',
  `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
  `deleted` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否删除 1是 0否',
  PRIMARY KEY (`id`)
) COMMENT='支付记录表'

本章完


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值