Double.doubleToLongBits(x)的含义 [英] Meaning of Double.doubleToLongBits(x)

查看:560
本文介绍了Double.doubleToLongBits(x)的含义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



当要求生成 equals(Object obj hashCode(),eclipse会生成以下内容:

  @Override 
public int hashCode(){
final int prime = 31;
int结果= 1;
长期温度;
temp = Double.doubleToLongBits(x);
结果=素数*结果+(int)(temp ^(temp> ;>> 32));
temp = Double.doubleToLongBits(y);
result = prime * result +(int)(temp ^(temp>>> 32));
返回结果;
}
@Override
public boolean equals(Object obj){
if(this == obj)
return true;
if(obj == null)
返回false;
if(getClass()!= obj.getClass())
return false;
Vec2D other =(Vec2D) obj;
if(Double.doubleToLongBits(x)!= Double.doubleToLongBits(other.x))
返回false;
if(Double.doubleTo LongBits(y)!= Double.doubleToLongBits(other.y))
返回false;
返回true;
}

Double.doubleToLongBits(x )?我不能简单地写 x!= other.x 吗?

解决方案

简短答案:Eclipse使用 Double.doubleToLongBits ,因为这就是 Double.equals 可以:


结果为 true 当且仅当参数不是 null 并且是一个Double对象,它表示 doubl e具有与此对象表示的 double 相同的值。为此,当且仅当方法 double 值才被视为相同。 /docs/api/java/lang/Double.html#doubleToLongBits(double) rel = noreferrer> doubleToLongBits(double) 返回相同的<$


长答案:JLS指定Double.equals之间的一些区别和==。对于 JLS 4.2中指定的区别.3 JLS 15.21.1


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


另一个问候 NaN


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


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


如您所见,两个双精度值可以与 == 进行比较,但实际上在数学和哈希中使用时对应于不同的行为表格。因此,当编写一个生成的相等方法时,Eclipse假定只有当且仅当所有可以对它们执行的操作都相同时,或者(等效地)如果将它们自动装箱并与<$ c $进行比较,两个双精度数才相等。 c>等于方法。如果在 double Double 之间进行切换,这尤其重要-相等属性在那里出现差异是特别出乎意料的。 / p>

当然,您可以随意偏离该假设:不管这是一个好主意,您都可以将特殊情况分配给许多可能的NaN表示形式,在这种情况下 Double.doubleToRawLongBits()更适合您的 equals hashCode 方法。同样,您的用例可能会将+0.0和-0.0的对象视为等效对象,并保证不能使用NaN值,在这种情况下,原始的 == 比较可能对于等于更好地工作(但是到那时,为 hashCode 模仿相同的条件变得困难)。


I am writing a class Vec2D, representing a 2 dimensional vector. I store x and y in doubles.

When asked to generate equals(Object obj and hashCode(), eclipse generated this:

@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;
}

What is the significance of Double.doubleToLongBits(x) in this context? Can I not simply write x != other.x?

解决方案

Short answer: Eclipse uses Double.doubleToLongBits because that's what Double.equals does:

The result is true if and only if the argument is not null and is a Double object that represents a double that has the same value as the double represented by this object. For this purpose, two double values are considered to be the same if and only if the method doubleToLongBits(double) returns the identical long value when applied to each.

Long answer: the JLS specifies a few differences between Double.equals and ==. For one difference specified in JLS 4.2.3 and JLS 15.21.1:

Positive zero and negative zero compare equal; thus the result of the expression 0.0==-0.0 is true and the result of 0.0>-0.0 is false. But other operations can distinguish positive and negative zero; for example, 1.0/0.0 has the value positive infinity, while the value of 1.0/-0.0 is negative infinity.

Another regards NaN:

If either operand is NaN, then the result of == is false but the result of != is true.

Indeed, the test x!=x is true if and only if the value of x is NaN.

As you can see, it's possible for two double values to compare with == but actually correspond to different behavior when used in math and hash tables. Thus, when writing a generated equality method, Eclipse makes the assumption that two doubles are only equal if and only if all operations that can be done to them are identical, or (equivalently) if they were autoboxed and compared with their equals methods. This is particularly important if switching between double and Double—it would be particularly unexpected for equality properties to differ there.

Of course, you're free to drift from that assumption: Regardless of whether it's a good idea, you may assign special cases to any of the many possible NaN representations, in which case Double.doubleToRawLongBits() would be a better match for your equals and hashCode methods. By the same token, your use case might treat objects with +0.0 and -0.0 as equivalent and guarantee that NaN values are not possible, in which case a raw == comparison may work better for equals (but at which point emulating the same criteria for hashCode becomes difficult).

这篇关于Double.doubleToLongBits(x)的含义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆