在 equals() 方法中比较双精度的正确方法

我的类中有双精度类型,并且必须重写 equals()/hashCode()。所以我需要比较双精度值。


哪个是正确的方法?


版本1:


boolean isEqual(double a, double b){

    return Double.doubleToLongBits(a) == Double.doubleToLongBits(b);}

版本2:


boolean isEqual(double a, double b){

    final double THRESHOLD = .0001;

    return Math.abs(a - b) < THRESHOLD;

}

double或者我应该完全避免原始并使用它的包装类型Double?这样我就可以使用Objects.equals(a,b), ifa和bare Double 。


慕容3067478
浏览 99回答 2
2回答

三国纷争

在 equals/hashcode 方法中推荐使用的方法[需要引用]是分别使用Double.doubleToLongBits()和Double.hashcode()。这是因为如果哈希码不同,则 equals 合约要求两个输入的计算结果为“不同”。反之则没有限制。(注意:事实证明Double.compare()内部使用,doubleToLongBits()但 API 没有指定。因此我不会推荐它。另一方面,hashCode()&nbsp;确实指定它使用doubleToLongBits()。)实际例子:@Overridepublic boolean equals(Object obj) {&nbsp; &nbsp; if (obj == null || getClass() != obj.getClass())&nbsp; &nbsp; &nbsp; &nbsp; return false;&nbsp; &nbsp; Vector2d other = (Vector2d)obj;&nbsp; &nbsp; return Double.doubleToLongBits(x) == Double.doubleToLongBits(other.x) &&&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;Double.doubleToLongBits(y) == Double.doubleToLongBits(other.y);}@Overridepublic int hashCode() {&nbsp; &nbsp; int hash = 0x811C9DC5;&nbsp; &nbsp; hash ^= Double.hashCode(x);&nbsp; &nbsp; hash *= 0x01000193;&nbsp; &nbsp; hash ^= Double.hashCode(y);&nbsp; &nbsp; hash *= 0x01000193;&nbsp; &nbsp; return hash;}

DIEA

double值不应该用作建立对象相等性及其hashcode的组件。这是因为浮点数存在固有的不精确性,并且人为地双饱和+/-Infinity为了说明这个问题:System.out.println(Double.compare(0.1d&nbsp;+&nbsp;0.2d,&nbsp;0.3d)); System.out.println(Double.compare(Math.pow(3e27d,&nbsp;127d),&nbsp;17e256d&nbsp;/&nbsp;7e-128d));印刷:1 0...这转化为以下两个错误陈述:0.1+0.2>0.3(3 * 1027)127&nbsp;== 17 * 10256&nbsp;/ (7 * 10-128)因此,你的软件会让你对两个不相等的相等数字或两个非常大或非常小的不相等数字相等采取行动。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java