繁体   English   中英

Double.doubleToLongBits(x)的含义

[英]Meaning of Double.doubleToLongBits(x)

我正在写一个类Vec2D ,代表一个二维向量。 我将xy存储在double s中。

当被要求生成equals(Object objhashCode() ,eclipse生成了这个:

@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    long temp;
    temp = Double.doubleToLongBits(x);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    temp = Double.doubleToLongBits(y);
    result = prime * result + (int) (temp ^ (temp >>> 32));
    return result;
}
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Vec2D other = (Vec2D) obj;
    if (Double.doubleToLongBits(x) != Double.doubleToLongBits(other.x))
        return false;
    if (Double.doubleToLongBits(y) != Double.doubleToLongBits(other.y))
        return false;
    return true;
}

Double.doubleToLongBits(x)在此上下文中的意义是什么? 我不能简单地写x != other.x吗?

简短回答:Eclipse使用Double.doubleToLongBits,因为这就是Double.equals的作用:

其结果是true ,当且仅当参数不null ,并且是双对象,它表示一个doubl具有相同的值作为电子double该对象表示。 为此,当且仅当方法doubleToLongBits(double)在应用于每个时返回相同的long值时,才认为两个double值相同。

答案很长:JLS指定了Double.equals和==之间的一些差异。 对于JLS 4.2.3JLS 15.21.1中指定的一个差异:

正零和负零比较相等; 因此,表达式0.0==-0.0的结果为true0.0>-0.0的结果为false 但其他操作可以区分正负零; 例如, 1.0/0.0的值为正无穷大,而1.0/-0.0值为负无穷大。

另一个问题是NaN

如果任一操作数是NaN,则==的结果为false!=的结果为true

实际上,当且仅当x的值是NaN时,测试x!=xtrue

正如您所看到的, 可以将两个double值与==进行比较,但实际上对应于在数学和哈希表中使用时的不同行为 因此,在编写生成的相等方法时,Eclipse假设只有当所有可以对它们执行的操作相同时,或者(等效地)它们被自动装箱并与它们的equals方法进行比较时,两个双精度才相等。 如果在doubleDouble之间切换特别意外的话,对于不同的等同属性,这一点尤为重要。

当然,你可以自由地偏离这个假设:不管它是否是一个好主意,你可以将特殊情况分配给许多可能的NaN表示中的任何一个,在这种情况下, Double.doubleToRawLongBits()将更适合你的equalshashCode方法。 出于同样的原因,您的用例可能会将+0.0和-0.0的对象视为等效对象,并保证NaN值不可能,在这种情况下,原始==比较可能对equals更好(但在此时仿效相同的条件)对于hashCode变得困难)。

因为==!=遵循IEEE-754双精度语义, Double.NaN != Double.NaN0.0 == -0.0 这些行为可能不是您想要的,因此Double.doubleToLongBits()将64位double数据转换为64位long数据,以便像位移和XOR这样的操作。

老实说,我会说使用doubleToLongBits是一个错误,因为如果你关心完全相等,你应该使用Double.doubleToRawLongBits() (它根本不对double数据执行任何翻译)。

快速浏览一下在线javadoc会产生这样的结果:

根据IEEE 754浮点“双格式”位布局返回指定浮点值的表示形式。

...

在所有情况下,结果都是一个长整数,当给予longBitsToDouble(long)方法时,将生成一个与doubleToLongBits参数相同的浮点值(除了所有NaN值都折叠为单个“规范”NaN)值)。

因此,它可能是标准化xydouble表示的一种方式,因为NaN可以具有多个double表示

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM