raw floating-point bits in '==' value object comparisons (again/still)
Remi Forax
forax at univ-mlv.fr
Mon Mar 11 13:33:57 UTC 2024
Last week, I explain at JChateau (think JCrete in France, less sun, more chateaux) how value types work from the user POV, among other subject describing the semantics of ==.
First, most of the attendee knew the semantics difference between == on double and Double.equals(). I suppose it's because people that attend to such (un-)conference have a more intimate knowledge of Java than an average developer. Second, no attendee knew that NaN was a prefix.
So it let me think again on that subject.
1) The argument that of Dan that we want to be able to create a class with two different NaN, does not hold because instead of storing the values as double, the values can be stored as long.
value class C {
private double d;
C(double d) { this.d = d; }
long bits() { return Double.doubleToRawLongBits(d); }
}
C c1 = new C(Double.longBitsToDouble(0x7ff0000000000001L));
C c2 = new C(Double.longBitsToDouble(0x7ff0000000000002L));
assert c1.bits() != c2.bits();
can be rewritten as
value class C {
private long l;
C(double d) { this.l = Double.doubleToRawLongBits(d); }
long bits() { return l; }
}
2) The de-duplication of value instances by the GC works with both the bitwise equivalence and the representational equivalence.
If the GC only de-duplicate the value instance based only on the bitwise equivalence, it is a valid algorithm under the representational equivalence.
So I not convinced that the bitwise equivalence should be choosen instead of the representational equivalence, for me two semantics instead of three is a win.
Rémi
More information about the valhalla-spec-observers
mailing list