天下事有难易乎?为之,则难者亦易矣;不为,则易者亦难矣。

Java 中的 BigDecimal 运算,如何解决精度丢失问题?

itzoo 594次浏览 0个评论

点击“终码一生”,关注,置顶公众号

每日技术干货,第一时间送达!



1、我们先看一个例子



可以看到在Java中进行浮点数运算的时候,会出现丢失精度的问题。那么我们如果在进行商品价格计算的时候,就会出现问题。很有可能造成我们手中有0.06元,却无法购买一个0.05元和一个0.01元的商品。


因为如上所示,他们两个的总和为0.060000000000000005。这无疑是一个很严重的问题,尤其是当电商网站的并发量上去的时候,出现的问题将是巨大的。可能会导致无法下单,或者对账出现问题。所以接下来我们就可以使用Java中的BigDecimal类来解决这类问题。


2、BigDecimal中的一些方法


构造器 描述
BigDecimal(int) 创建一个具有参数所指定整数值的对象。
BigDecimal(double) 创建一个具有参数所指定双精度值的对象。
BigDecimal(long) 创建一个具有参数所指定长整数值的对象。
BigDecimal(String) 创建一个具有参数所指定以字符串表示的数值的对象。


方法 描述
add(BigDecimal) BigDecimal对象中的值相加,然后返回这个对象。
subtract(BigDecimal) BigDecimal对象中的值相减,然后返回这个对象。
multiply(BigDecimal) BigDecimal对象中的值相乘,然后返回这个对象。
divide(BigDecimal) BigDecimal对象中的值相除,然后返回这个对象。
toString() 将BigDecimal对象的数值转换成字符串。
doubleValue() 将BigDecimal对象中的值以双精度数返回。
floatValue() 将BigDecimal对象中的值以单精度数返回。
longValue() 将BigDecimal对象中的值以长整数返回。
intValue() 将BigDecimal对象中的值以整数返回。


3、值得注意的是如果要想无精度丢失的情况下计算结果,那么需要把double,float类型的参数转化为String类型的


使用BigDecimal(String)这个构造方法进行构造,去获取结果。不然还是没有效果。




4、在一般开发过程中,我们数据库中存储的数据都是float和double类型的。


在进行拿来拿去运算的时候还需要不断的转化,这样十分的不方便。这里我写了一个工具类,以后可以直接使用。


public class BigDecimalUtil {
 
    private BigDecimalUtil() {
 
    }
 
    public static BigDecimal add(double v1, double v2) {
        // v1 + v2
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.add(b2);
    }
 
    public static BigDecimal sub(double v1, double v2) {
        //v1-v2
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.subtract(b2);
    }
 
    public static BigDecimal mul(double v1, double v2) {
        //v1*v2
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        return b1.multiply(b2);
    }
 
    public static BigDecimal div(double v1, double v2) {
        //v1/v2
        BigDecimal b1 = new BigDecimal(Double.toString(v1));
        BigDecimal b2 = new BigDecimal(Double.toString(v2));
        // 2 = 保留小数点后两位 ROUND_HALF_UP = 四舍五入
        return b1.divide(b2, 2, BigDecimal.ROUND_HALF_UP);// 应对除不尽的情况
    }
}


来源:blog.csdn.net/yin_xing_ye/article/details/94596247


PS:防止找不到本篇文章,可以收藏点赞,方便翻阅查找哦。


往期推荐



告别收费 XShell,徒手用 Java 写了一个 SSH 工具!就是爽…

MyBatis 批量插入几千条数据,请慎用foreach

SpringBoot 实现万能文件在线预览,已开源,真香!!!

基于Springboot+Dubbo+Nacos 注解方式实现微服务调用!

巧用 Java 8 的 Stream 来优化代码,太简洁了!

一文读懂 Dubbo 的设计思想,真优秀!



ITZOO版权所有丨如未注明 , 均为原创丨转载请注明来自IT乐园 ->Java 中的 BigDecimal 运算,如何解决精度丢失问题?
发表我的评论
取消评论
表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址