Java 如何正确比较两个浮点数

看下面这段代码,将 d1 和 d2 两个浮点数进行比较,输出的结果会是什么?

double d1 = .1 * 3;
double d2 = .3;
System.out.println(d1 == d2);

按照正常逻辑来看,d1 经过计算之后的结果应该是 0.3,最后打印的结果应该是 true,对吧?但是运行一下就会发现结果并不是 true 而是 false

输出一下 d1,发现得到的答案不是想象中的 0.3 而是 0.30000000000000004,所以和 d2 进行比较结果自然是 false

如何正确地比较浮点数(单精度的 float 和双精度的 double),不单单是 Java 特定的问题,在计算机的内存中,存储浮点数时使用的是 IEEE 754 标准,就会有精度的问题。

存储和转换的过程中浮点数容易引起一些较小的舍入误差,正是这个原因,导致在比较浮点数的时候,不能使用“==”操作符——要求严格意义上的完全相等。

那么如何正确的比较浮点数呢?这里有两种方案。

方案1:比较绝对值误差

第一种方案是允许两个值之间存在一点误差(指定一个阈值),使用 Math.abs() 方法来计算两个浮点数之间差异的绝对值,如果这个差异在阈值范围之内,我们就认为两个浮点数是相等的。

final double THRESHOLD = .0001;

double d1 = .1 * 3;
double d2 = .3;

if (Math.abs(d1 - d2) < THRESHOLD) {
   
    System.out.println("d1 和 d2 相等");
} else {
   
    System.out.println("d1 和 d2 不相等");
}

Math.abs() 方法用来返回 double 的绝对值,如果 double 小于 0,则返回 double 的正值,否则返回 double。也就是说,abs() 后的结果绝对大于 0,如果结果小于阈值(THRESHOLD),我们就认为 d1d2 相等。

方案2:BigDecimal

第二种方案是使用 BigDecimal 类,可以指定要舍入的模式和精度,这样

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

川峰

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

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

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

打赏作者

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

抵扣说明:

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

余额充值