BigDecimal基本使用与闭坑介绍

前言:我们在开发过程中经常使用BigDecimal 来做金额数据类型使用,特别是保留小数点2位,提高科学计算的准确度,但是BigDecimal 使用不当也会导致精度丢失问题,与double 类似情况。

一. 首先我们来验证下上面说的问题 ,程序员先上代码

/**
 * @author zhaoyy
 * @version 1.0
 * @description BigDecimal 类型使用
 * @date 2022/6/9
 **/
public class BigDecimalTest {

    public static void main(String[] args) {
        BigDecimal bigDecimal=new BigDecimal(66);
        System.out.println(bigDecimal);
        bigDecimal=new BigDecimal("6.6");
        System.out.println(bigDecimal);
        bigDecimal=new BigDecimal(6.6);
        System.out.println(bigDecimal);

        // 推荐使用
        bigDecimal= BigDecimal.valueOf(6.6);
        System.out.println(bigDecimal);
    }
}

输出内容:

66
6.6
6.5999999999999996447286321199499070644378662109375
6.6

上面倒数第二输出,就存在精度丢失问题,推荐使用BigDecimal.valueOf()方法来完成初始化值,少用构造方法对BigDecimal赋值,BigDecimal构造器会对不同数据类型调用不通的构造方法,具体代码大家可以点开源码了解下。而valueOf() 方法在使用double 方法时进行类型转换成toString具体请看下下面源码展示。

源码展示:
double 类型构造方法:
在这里插入图片描述
在这里插入图片描述
总结:
1 .BigDecimal 构造器初始化值对应 double,flot 类型需要考虑是否支持精度丢失问题
2. 造成丢失精度的原因,是数据类型转换过程中会将数据转换成二进制数类型,当十进制小数位转换二进制的时候肯会出现无限循环或者超过浮点数尾数的长度,最终导致精度丢失的问题。
3. 建议开发中使用BigDecimal.valueOf()尽量规避这类问题

讲了这么多,给大家分享个BigDecimal 基本操作工具类

import java.math.BigDecimal;

/**
 * @author zhaoyy
 * @version 1.0
 * @description bigDecimal 工具类
 * @date 2022/6/9
 **/
public class BigDecimalUtils {

    public static BigDecimal doubleAdd(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }
    public static BigDecimal floatAdd(float v1, float v2) {
        BigDecimal b1 = new BigDecimal(Float.toString(v1));
        BigDecimal b2 = new BigDecimal(Float.toString(v2));
        return b1.add(b2);
    }
    public static BigDecimal doubleSub(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2);
    }
    public static BigDecimal floatSub(float v1, float v2) {
        BigDecimal b1 = new BigDecimal(Float.toString(v1));
        BigDecimal b2 = new BigDecimal(Float.toString(v2));
        return b1.subtract(b2);
    }

    public static BigDecimal doubleMul(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2);
    }
    public static BigDecimal floatMul(float v1, float v2) {
        BigDecimal b1 = new BigDecimal(Float.toString(v1));
        BigDecimal b2 = new BigDecimal(Float.toString(v2));
        return b1.multiply(b2);
    }

    public static BigDecimal doubleDiv(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        // 保留小数点后两位 ROUND_HALF_UP = 四舍五入
        return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);
    }
    public static BigDecimal floatDiv(float v1, float v2) {
        BigDecimal b1 = new BigDecimal(Float.toString(v1));
        BigDecimal b2 = new BigDecimal(Float.toString(v2));
        // 保留小数点后两位 ROUND_HALF_UP = 四舍五入
        return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);
    }
    /**
     * 比较v1 v2大小
     * @param v1
     * @param v2
     * @return v1>v2 return 1  v1=v2 return 0 v1<v2 return -1
     */
    public static int doubleCompareTo(double v1, double v2) {
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return  b1.compareTo(b2);
    }
    public static int floatCompareTo(float v1, float v2) {
        BigDecimal b1 = new BigDecimal(Float.toString(v1));
        BigDecimal b2 = new BigDecimal(Float.toString(v2));
        return  b1.compareTo(b2);
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜鸟-要努力

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值