Java中如何比较浮点数是否相等

本文介绍了在Java中如何正确地比较浮点数的值及对象。对于值的比较,考虑到精度损失的问题,提出了一种基于容差的方法;而对于对象的比较,则通过使用Double.doubleToLongBits方法来解决NaN的特殊问题。

###0.前言
所谓“相等”,有两种理解,一种是浮点数的值相等,另一种是指对象相同。
###1.值相等
浮点数能表示的精度是有限的,在计算过程中不可避免的会出现截尾而损失精度,而且传感器等外部设备输入的数据本身也有误差,所以如果要判断一个浮点数double_x是否等于0,用double_x == 0这样的判断是不合适的,如果double_x是一系列计算的结果或者是外部传感器的输入值,那么它几乎不可能是0,它大概率是一个接近0的小数,比如0.000002,那么,这时候要比较double_x是否等于0,首先要明确自己的精度要求,比如因为传感器有误差,小于0.001的数都可以认为等于0,那么就定义epsilon=0.001:

final double epsilon = 0.001;
if(Math.abs(double_x - 0) < epsilon)
{
	return true;
}

###2.对象相同
判断两个double变量值严格相等,一般会直接用double_x == double_y来做比较,这样做一般没有问题,但是如果本意是比较两个浮点数对象是否相同(double_x == double_y是比较两个对象值是否严格相同),对象相同和值严格相等是不一样的,原因是java遵循IEEE 754浮点数标准,在这个标准中规定NaN与任何值比较皆不等,如果double_xdouble_y的值都是NaN,这个时候他们是相同的对象,但double_x == double_y会返回false。解决方法是,判断浮点数值是否严格相同,要用Double.doubleToLongBits将double值转换过后再比较

if(Double.doubleToLongBits(double_x) == Double.doubleToLongBits(double_y))

Double.doubleToLongBits说明:

Returns a representation of the specified floating-point value according to the IEEE 754 floating-point “double format” bit layout.
Bit 63 (the bit that is selected by the mask 0x8000000000000000L) represents the sign of the floating-point number. Bits 62-52 (the bits that are selected by the mask 0x7ff0000000000000L) represent the exponent. Bits 51-0 (the bits that are selected by the mask 0x000fffffffffffffL) represent the significand (sometimes called the mantissa) of the floating-point number.

If the argument is positive infinity, the result is 0x7ff0000000000000L.

If the argument is negative infinity, the result is 0xfff0000000000000L.

If the argument is NaN, the result is 0x7ff8000000000000L.

In all cases, the result is a long integer that, when given to the longBitsToDouble(long) method, will produce a floating-point value the same as the argument to doubleToLongBits (except all NaN values are collapsed to a single “canonical” NaN value).

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值