Java's ByteBuffer compareTo: Comparing a byte to itself "For float and double"?
Inside of Java's ByteBuffer is the method compareTo for implementing Comparable<ByteBuffer>...
public int compareTo(ByteBuffer that) {
int n = this.position() + Math.min(this.remaining(), that.remaining());
for (int i = this.position(), j = that.position(); i < n; i++, j++) {
byte v1 = this.get(i);
byte v2 = that.get(j);
if (v1 == v2)
continue;
if ((v1 != v1) && (v2 != v2)) // For float and double
continue;
if (v1 < v2)
return -1;
return +1;
}开发者_Go百科
return this.remaining() - that.remaining();
}
What is the point of if ((v1 != v1) && (v2 != v2)) // For float and double
?
If I write this kind of code, I'm warned about comparing identical expressions.
In that particular code, it doesn't make sense. However, that's a popular idiom for floats and doubles. Both can be "NaN", meaning they don't represent a valid, comparable number. NaN is technically not equal to anything, even itself, so for a float or double that code would check to see if both are NaN, which is enough in this case to call them equal.
I seems the Buffer classes are generated from a common source code template, this particular line only makes sense for the float and double versions to detect the special case where both numbers are NANs.
Double.NaN == Double.NaN
and Float.NaN == Float.NaN
gives false
.
See also end of JLS 4.2.3:
The equality operator == returns false if either operand is NaN, and the inequality operator != returns true if either operand is NaN (§15.21.1).
As all the other anwsers already pointed out, it the check for Float.NaN
and Double.NaN
. They should have used Float.isNan
and Double.isNaN
. This would have made that code way more readable. Long story short: Don't emulate.
精彩评论