I am writing a class Vec2D
, representing a 2 dimensional vector. I store x
and y
in double
s.
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
?
lang. Double. doubleToLongBits() method of Java Double class is a built-in function in java that returns a representation of the specified floating-point value according to the IEEE 754 floating-point “double format” bit layout.
public static final double POSITIVE_INFINITY. A constant holding the positive infinity of type double . It is equal to the value returned by Double.
Double. It represents single-precision numbers. It represents double-precision numbers. Width is 32 bits and the range is 1.4e–045 to 3.4e+038.
Short answer: Eclipse uses Double.doubleToLongBits because that's what Double.equals does:
The result is
true
if and only if the argument is notnull
and is a Double object that represents adoubl
e that has the same value as thedouble
represented by this object. For this purpose, twodouble
values are considered to be the same if and only if the methoddoubleToLongBits(double)
returns the identicallong
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
istrue
and the result of0.0>-0.0
isfalse
. But other operations can distinguish positive and negative zero; for example,1.0/0.0
has the value positive infinity, while the value of1.0/-0.0
is negative infinity.
Another regards NaN
:
If either operand is NaN, then the result of
==
isfalse
but the result of!=
istrue
.Indeed, the test
x!=x
istrue
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).
Because ==
and !=
follow IEEE-754 semantics for doubles, Double.NaN != Double.NaN
and 0.0 == -0.0
. These behaviors may not be what you want, so Double.doubleToLongBits()
converts the 64 bits of double
data to 64 bits of long
data so that operations like bit shifts and XOR work.
Honestly, though, I would say that the use of doubleToLongBits
is a bug here, since if you care about exact equality you should be using Double.doubleToRawLongBits()
(which does not perform any translations on the double
data at all) instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With