浮点数运算的精度问题及如何解决

本文探讨了浮点数运算中精度丢失的原理,通过代码示例展示了二进制表示的局限性,并介绍了如何使用BigDecimal避免精度问题。重点在于理解计算机存储浮点数的机制和使用BigDecimal进行精确计算的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题

浮点数运算精度丢失代码演示:

float a = 2.0f - 1.9f;
float b = 1.8f - 1.7f;
System.out.println(a);      //0.100000024
System.out.println(b);      //0.099999905
System.out.println(a==b);   //false

为什么会出现这个问题呢?

这个和计算机保存浮点数的机制有很大关系。我们知道计算机是二进制的,而且计算机在表示一个数字时,宽度是有限的,无限循环的小数存储在计算机时,只能被截断,所以就会导致小数精度发生损失的情况。这也就是解释了为什么浮点数没有办法用二进制精确表示。

就比如说十进制下的 0.2 就没办法精确转换成二进制小数:

// 0.2 转换为二进制数的过程为,不断乘以 2,直到不存在小数为止,
// 在这个计算过程中,得到的整数部分从上到下排列就是二进制的结果。
0.2 * 2 = 0.4 -> 0
0.4 * 2 = 0.8 -> 0
0.8 * 2 = 1.6 -> 1
0.6 * 2 = 1.2 -> 1
0.2 * 2 = 0.4 -> 0(发生循环)

所以 0.2(D) = 0.00110…(B)。

关于浮点数的更多内容,可以参考计算机系统基础(四)浮点数这篇文章。

解决

我们需要用到BigDecimal类
BigDecimal 可以实现对浮点数的运算,不会造成精度丢失。通常情况下,大部分需要浮点数精确运算结果的业务场景(比如涉及到money的场景)都是通过 BigDecimal 来做的。

BigDecimal a = new BigDecimal("2.0");
BigDecimal b = new BigDecimal("1.9");
BigDecimal c = new BigDecimal("1.8");
BigDecimal d = new BigDecimal("1.7");

BigDecimal x = a.subtract(b);       //a-b
BigDecimal y = c.subtract(d);       //c-d
System.out.println(x);              //0.1
System.out.println(y);              //0.1
System.out.println(x.equals(y));   //true

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值